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. |
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. |
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. |