Page 1 of 1

Getting part of bitmap from TRVCustomPrint only

Posted: Mon Jan 28, 2008 5:16 am
by Michael Pro
Sergey, I've got one question.
In my project I need to get a part of bitmap preview in scale size.
Could you help me and tell, how to modify a part of MakePreview to work with big size images?

I need smth like:

MakePartPreview(PageNo: Integer; Height, Width: Intger; PartRect: TRect; destBmp: TBitmap)

I've used MakeScaledPreview - but for big bitmaps I've got "Out of memory exception". I understand, that the whole bitmap wouldn't used anyway, but I've really puzzled, how to make source work right. Maybe I didn't used cliping and view areas right - but I've got no ideas about that :(

In prototype function, Height and Width defines true size of needed bitmap for outputing, PartRect defines rectangle, which needed to cut into destination bitmap in this true scaling.
I think, that this function could be very useful for all of users of TRichView product.

Best regards,
Michael.

Posted: Mon Jan 28, 2008 10:23 am
by Michael Pro
Finally, I've solved this trouble as I needed. Here is a small contribution.
It's very raw source, but it works in my application :)

Some comments:
FRichEdit - internal editor;
fmMain - main form with TRVPrint on it
Printer - instance of TRVPrint on main form
ScaleX, ScaleY - scales for X-axis and Y-axis. 1 is for 100 percent.

Code: Select all

procedure TopLeftCanvasDraw(Canvas: TCanvas; ScaleX, ScaleY: Extended; Width, Height: Integer);
var
  EMF: TMetafile;
  EMFCanvas: TMetafileCanvas;
  dc: hdc;
  LocalHandle: THandle;
  tHeight, tWidth: Integer;
  rgn: HRGN;
begin
    //Assigning sources and reformating pages
    fmMain.Printer.AssignSource(FRichEdit);
    fmMain.Printer.FormatPages(rvDoAll);
    //Getting HDC for further actions
    LocalHandle := GetDC(0);
    //Creating main metafile
    EMF := TMetafile.Create;
    try
      //Creating canvas
      EMFCanvas := TMetafileCanvas.Create(EMF, LocalHandle);
      try
         //Calculating height and width
        EMF.Width := Trunc(fmMain.Printer.Preview100PercentWidth * ScaleX);
        EMF.Height := Trunc(fmMain.Printer.Preview100PercentHeight * ScaleY);
        //Creating clipping region and Selecting it
        rgn := CreateRectRgn(0, 0, Width, Height);
        SelectClipRgn(EMFCanvas.Handle, rgn);
        //Outputing first page in component
        //actually, we can make it in cycle for other pages, but it doesn't
        //needed in my project
        fmMain.Printer.DrawPreview(1, EMFCanvas, Rect(0, 0, EMF.Width, EMF.Height));
        //Clear graphic objects
        SelectClipRgn(Canvas.Handle, 0);
        DeleteObject(rgn);
      finally
        EMFCanvas.Free;
      end;
      //Output on canvas
      Canvas.Draw(FX, FY, EMF);
    finally
      EMF.Free;
      ReleaseDC(0, LocalHandle);
    end;
end;
By the way, Sergey, I've found, that the better way is to use Metafiles, not Bitmaps - it cause a lot of troubles with big images - I don't know graphic side of WinAPI and Delphi so well, and I got some troubles by making this code.
Anyway, if you consider, that this code is good enough for making some major improvements or it's good for some ideas, you can use it freely.
---
Best regards,
Michael.

PS If you have a better suggestion of source, I would be very appreciate.