Printing JPEG's

Category

Code Based - General

Question

I need to be able to print JPEG's. How would I do that?

Solution

This can be done through the use of the PrintImageRect method and OnDecodeImage event. These allow native image format storage (such as JPG or TIFF) in the Rave file (the one created by TReportFiler) for space savings. The PrintImageRect method is called with the X1,Y1,X2,Y2 parameters like PrintBitmapRect; but instead of a bitmap object, a stream containing the image data and an optional identifier is passed. Here is some sample code from an OnPrint event.

Delphi Example:

uses JPEG;

procedure TForm1.ReportSystem1Print(Sender: TObject);

var
  Stream: TMemoryStream;
  Image: TJPEGImage;

begin
  With Sender as TBaseReport do begin
    Stream := TMemoryStream.Create;
    Image := TJPEGImage.Create;
    try
      Image.LoadFromFile('image1.jpg');
      Image.SaveToStream(Stream);
      Stream.Position := 0;
      PrintImageRect(1,1,3,3.5,Stream,'JPG');
    finally
      Image.Free;
      Stream.Free;
    end; { tryf }
  end; { with }
end;

C++Builder Example:

#include 
#define TBitmap Graphics::TBitmap
void __fastcall TForm1::ReportSystem1Print(TObject *Sender)
{
  TBaseReport* bp = dynamic_cast(Sender);
  TMemoryStream* Stream;
  TJPEGImage* Image;

  Stream = new TMemoryStream();
  Image = new TJPEGImage();
  try {
    Image->LoadFromFile("image1.jpg");
    Image->SaveToStream(Stream);
    Stream->Position = 0;
    bp->PrintImageRect(1,1,3,3,Stream,"JPG");
  }// try
  __finally {
    delete Image;
    delete Stream;
  }// tryf
}

The previous code will store the JPG in its native format in the report file. The next step is to define an OnDecodeImage event to allow Rave to convert this image data to a bitmap when it needs it. This would normally appear on a TFilePrinter or TFilePreview component, but can also be defined in a TReportSystem component. Here's an example of an OnDecodeImage event.

Delphi Example:

procedure TForm1.ReportSystem1DecodeImage(Sender: TObject;
  ImageStream: TStream; ImageType: String; Bitmap: TBitmap);

var
  Image: TJPEGImage;

begin
  If ImageType = 'JPG' then begin
    Image := TJPEGImage.Create; // Create a TJPEGImage class
    try
      Image.LoadFromStream(ImageStream); // Load up JPEG image from ImageStream
      Image.DIBNeeded; // Convert JPEG to bitmap format
      Bitmap.Assign(Image);
    finally
      Image.Free;
    end;
  end; { if }
end;

C++Builder Example:

void __fastcall TForm1::ReportSystem1DecodeImage(TObject *Sender,
      TStream *ImageStream, AnsiString ImageType, TBitmap *Bitmap)
{
  TJPEGImage* Image;

  if (ImageType == "JPG") {
    Image = new TJPEGImage(); // Create a TJPEGImage class
    try {
      Image->LoadFromStream(ImageStream); // Load up JPEG image from ImageStream
      Image->DIBNeeded(); // Convert JPEG to bitmap format
      Bitmap->Assign(Image);
    }// try
    __finally {
      delete Image;
    }// tryf
  }// if
}