Cropping a Bitmap (Delphi 4.0)

Take the following steps to add code that lets you select an area with a mouse, crop the display to show only that area, and trim the bitmap to match the selected area. (This example uses both cropping and trimming, so that you can see the difference.)

1.

Start with the project that you created in Loading and Displaying an Image.

2.

Add the following variables to the Private section in your main form:

    Cropping: Boolean; //the state when the mouse is used for cropping
    StartX: Integer; //Starting X position in screen pixels
    StartY: Integer; //Starting Y position in screen pixels
    EndX: Integer; //Ending X position in screen pixels
    EndY: Integer; //Ending Y position in screen pixels

3.

image\btncmd.gif Add a button to your form and name it as follows:

 

Name

Caption

 

Button1

Button1

 

Put it control at the top of the form to keep it away from the image.

4.

Code the Button1 click’s Procedure as the follwing, in online help; you can use the Edit pull-down menu to copy the block of code.

procedure TForm1.Button1Click(Sender: TObject);
var
   sRet: Smallint;
begin
   //Set the scale mode to twips so that we do not have to
   //translate mouse coordinates
   LEADRasterView1.ScaleMode := 1;
   //Initialize cropping so that you can do it more than once
   if (Cropping = True) then
   begin
      //Set the clipping area to match the image.
      LEADRasterView1.SetDstClipRect ( LEADRasterView1.DstLeft,
                     LEADRasterView1.DstTop,
                                          LEADRasterView1.DstWidth,
                                          LEADRasterView1.DstHeight,
                                          sRet ) ;
        //Display the image
        LEADRasterView1.ForceRepaint (sRet);
   end;
    //Set a global variable to let other events know that you are cropping
    Cropping := True;
    //Set the pointer to a crosshair
    LEADRasterView1.MousePointer := 2;
end;

5.

Handle the LEADRasterView1 control's OnMouseDown2 event, and code LEADRasterView1MouseDown2 as follows:

procedure TForm1.LEADRasterView1MouseDown2 (Sender: TObject; Button, 
  Shift: Smallint; x, y: Integer);
begin
   //Save the starting position
   StartX := Trunc(x);
   StartY := Trunc(y);
   //Make the rubberband invisible until the mouse moves
   LEADRasterView1.RubberBandVisible := False;
end;

6.

Handle the LEADRasterView1 control's OnMouseMove2 event, and code LEADRasterView1MouseMove2 as follows:

procedure TForm1.LEADRasterView1MouseMove2 (Sender: TObject; Button, 
  Shift: Smallint; x, y: Integer);
var
   rbX, rbY, rbWidth, rbHeight: Single;
   sRet: smallint;
begin
   if ((Cropping = True) And (Button = 1)) then
   begin
      //Get the current mouse position
      EndX := Trunc(x);
      EndY := Trunc(y);
      //Determine the origin of the rubberband rectangle, regardless of which way the mouse moves.
      if (EndX > StartX) then
         rbX := StartX
      else
         rbX := EndX;

      if (EndY > StartY) then
         rbY := StartY
      else
         rbY := EndY;
      //Determine the height and width of the rubberband rectangle
      rbHeight := Abs(StartY - EndY);
      rbWidth := Abs(StartX - EndX);
      //Set the rubberband rectangle
      LEADRasterView1.SetRubberBandRect (rbX, rbY, rbWidth, rbHeight, sRet);
      //Alternatively, you could use the following properties to set the
      //rubberband rectangle.
      LEADRasterView1.RubberBandHeight:= rbHeight;
      LEADRasterView1.RubberBandLeft:= rbX;
      LEADRasterView1.RubberBandTop:= rbY;
      LEADRasterView1.RubberBandWidth:= rbWidth;
      //Make the rubberband rectangle visible
      LEADRasterView1.RubberBandVisible:= True;
   end;
end;

7.

Handle the LEADRasterView1 control's OnMouseUp2 event, and code LEADRasterView1MouseUp2 as follows:

procedure TForm1.LEADRasterView1MouseUp2 (Sender: TObject; Button,
  Shift: Smallint; x, y: Integer);
var
   CropLeft, CropTop, CropWidth, CropHeight: Single;
   sRet: smallint;
begin
   if (Cropping = True) then
   begin
       //Get the current mouse position
      EndX := Trunc(x);
      EndY := Trunc(y);
      //Get the origin of the clipping rectangle.
      //Allow for different mouse drag directions
      if (StartX < EndX) then
         CropLeft := StartX
      else
         CropLeft := EndX;

      if (StartY < EndY) then
         CropTop := StartY
      else
         CropTop := EndY;
      //Get the height and width of the cropped area
      CropWidth := Abs(EndX - StartX);
      CropHeight := Abs(EndY - StartY);
      //Crop and repaint the image
      LEADRasterView1.SetDstClipRect (CropLeft, CropTop, CropWidth, CropHeight, sRet);
      LEADRasterView1.ForceRepaint ( sRet ) ;
      LEADRasterView1.RubberBandVisible := False;
      LEADRasterView1.MousePointer := 0 ;//Default
   end;
end;

8.

image\btncmd.gif Add a button to your form and name it as follows:

 

Name

Caption

 

Button2

Trim

 

This button will be used to trim the bitmap in memory and redisplay the bitmap.

 

Put it at the top of the form to keep it away from the image.

9.

Code the Button2 click’s procedure as the following. In online help, you can use the Edit pull-down menu to copy the block of code.

procedure TForm1.Button2Click(Sender: TObject);
var
   XFactor, YFactor: single;
   NewLeft, NewTop, NewWidth, NewHeight: single;
   HeightFactor, WidthFactor: single;
   HeightAllowed, WidthAllowed: single;
   RasterProc: LEADRasterProcess;
   sRet: smallint;
begin
   RasterProc:= CreateComObject (CLASS_LEADRasterProcess) as LEADRasterProcess;
   Screen.Cursor := crHourGlass;
   //Use the clipping rectangle's percentage offsets in the image rectangle
   //to determine the trimmed rectangle in the bitmap.
   //Using percentages allows for the possibility that the image is zoomed.
    XFactor := LEADRasterView1.Raster.BitmapWidth / LEADRasterView1.DstWidth;
    YFactor := LEADRasterView1.Raster.BitmapHeight / LEADRasterView1.DstHeight;
    NewTop := (LEADRasterView1.DstClipTop - LEADRasterView1.DstTop) * YFactor;
    NewLeft := (LEADRasterView1.DstClipLeft - LEADRasterView1.DstLeft) * XFactor;
    NewWidth := LEADRasterView1.DstClipWidth * XFactor;
    NewHeight := LEADRasterView1.DstClipHeight * YFactor;
    //Make sure display rectangles are automatically adjusted.
    LEADRasterView1.AutoSetRects := True;
    //Trim the bitmap.
    RasterProc.Trim ( LEADRasterView1.Raster, NewLeft, NewTop, NewWidth, NewHeight);
    //Size and redisplay the control, using the new bitmap size.
    //Set the variables used for preserving the aspect ratio.
    //Allow for a border of 1/8 of the form size.
    //The units of measure do not matter, since we are calculating proportions.
    HeightFactor := LEADRasterView1.Raster.BitmapHeight;
    WidthFactor := LEADRasterView1.Raster.BitmapWidth;
    HeightAllowed := Height - (Height / 4);
    WidthAllowed := Width - (Width / 4);
    //Center the LEAD control on the form, preserving the aspect ratio.
    //Check to see if using the maximum width will make the image too tall.
    //Set the dimensions based on the result.
   if ((WidthAllowed * HeightFactor) / WidthFactor) < HeightAllowed then
   begin
       LEADRasterView1.Left := Trunc(Width / 8);
      LEADRasterView1.Width := Trunc(WidthAllowed);
      LEADRasterView1.Height := Trunc((LEADRasterView1.Width * HeightFactor) / WidthFactor);
      LEADRasterView1.Top := Trunc((Height - LEADRasterView1.Height) / 2);
   end
   else
   begin
      LEADRasterView1.Top := Trunc(Height / 8);
      LEADRasterView1.Height:= Trunc(HeightAllowed);
      LEADRasterView1.Width := Trunc((LEADRasterView1.Height * WidthFactor) / HeightFactor);
      LEADRasterView1.Left := Trunc((Width - LEADRasterView1.Width) / 2);
   end;
   //Turn off scroll bars to make sure we use the full client area.
   LEADRasterView1.AutoScroll := False;
   //Set the image display size to match the LEAD control
   LEADRasterView1.SetDstRect (0, 0, LEADRasterView1.ScaleWidth, LEADRasterView1.ScaleHeight, sRet );
   LEADRasterView1.SetDstClipRect (0, 0, LEADRasterView1.ScaleWidth, LEADRasterView1.ScaleHeight, sRet ) ;
   //Display the image
   LEADRasterView1.ForceRepaint (sRet);
   Screen.Cursor := crDefault;
end;

10.

On the Project pull-down menu, use the Import Type library… and select the LEAD Raster Process object library (14.5).

11.

At the beginning of the Unit1 file, add LTRASTERPROCLib_TLB to the uses section. For example:

Uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, LTRASTERPROCLib_TLB;

12.

Run your program to test it.