Cropping a Bitmap (C++ Builder 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:

bool Cropping; //the state when the mouse is used for cropping
int StartX; //Starting X position in screen pixels
int StartY; //Starting Y position in screen pixels
int EndX; //Ending X position in screen pixels
int EndY; //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.

void __fastcall TForm1::Button1Click(TObject *Sender)
{
 //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)
{
 //Set the clipping area to match the image->
LEADRasterView1->SetDstClipRect (LEADRasterView1->DstLeft,
    LEADRasterView1->DstTop,
LEADRasterView1->DstWidth,
LEADRasterView1->DstHeight);
//Display the image
LEADRasterView1->ForceRepaint ();
 }
//Set a global variable to let other events know that you are cropping
Cropping = True;
//Set the pointer to a crosshair
LEADRasterView1->MousePointer = 2;
}

5.

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

void __fastcall TForm1::LEADRasterView1MouseDown2 (TObject *Sender,
short Button, short Shift, long x, long y)
{
 //Save the starting position
StartX= x;
StartY= y;
//Make the rubberband invisible until the mouse moves
LEADRasterView1->RubberBandVisible = False;
}

6.

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

void __fastcall TForm1::LEADRasterView1MouseMove2(TObject *Sender,
short Button, short Shift, long x, long y)
{
 float rbX, rbY, rbWidth, rbHeight;

 if ((Cropping) && (Button == 1))
{
 //Get the current mouse position
EndX = x;
EndY = y;
//Determine the origin of the rubberband rectangle, regardless of which way the mouse moves
if (EndX > StartX)
 rbX = StartX;
else
 rbX = EndX;

if (EndY > StartY)
 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);
//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 e= True;
 }
}

7.

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

void __fastcall TForm1::LEADRasterView1MouseUp2 (TObject *Sender,
short Button, short Shift, long x, long y)
{
 float CropLeft, CropTop, CropWidth, CropHeight;
 if (Cropping)
{
 //Get the current mouse position
 EndX= x;
EndY= y;
//Get the origin of the clipping rectangle->
//Allow for different mouse drag directions
if (StartX < EndX)
 CropLeft = StartX;
else
 CropLeft = EndX;

if (StartY < EndY)
 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);
LEADRasterView1->ForceRepaint () ;
LEADRasterView1->RubberBandVisible e = False;
LEADRasterView1->MousePointer = crDefault;
}
}

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.

void __fastcall TForm1::Button2Click(TObject *Sender)
{
 float XFactor, YFactor;
float NewLeft, NewTop, NewWidth, NewHeight;
float HeightFactor, WidthFactor;
float HeightAllowed, WidthAllowed;
LEADRasterProcess * pRasterProc;

 CoCreateInstance(CLSID_LEADRasterProcess, NULL, CLSCTX_ALL,
IID_ILEADRasterProcess, (void**)&pRasterProc);

 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.
pRasterProc->Trim ( LEADRasterView1->Raster, NewLeft, NewTop, NewWidth, NewHeight);
pRasterProc-> Release ( ) ;
//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)
{
 LEADRasterView1->Left = Width / 8;
LEADRasterView1->Width = WidthAllowed;
LEADRasterView1->Height = (LEADRasterView1->Width * HeightFactor) / WidthFactor;
LEADRasterView1->Top = (Height - LEADRasterView1->Height) / 2;
}
else
{
LEADRasterView1->Top = Height / 8;
LEADRasterView1->Height= HeightAllowed;
LEADRasterView1->Width = (LEADRasterView1->Height * WidthFactor) / HeightFactor;
LEADRasterView1->Left = (Width - LEADRasterView1->Width) / 2;
}
//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 );
LEADRasterView1->SetDstClipRect (0, 0, LEADRasterView1->ScaleWidth, LEADRasterView1->ScaleHeight ) ;
//Display the image
LEADRasterView1->ForceRepaint ();
Screen->Cursor = crDefault;
}

10.

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

11.

The beginning of Unit1 file, include the file:

#include "LTRASTERPROCLib_TLB.h"

12.

Run your program to test it.