Cropping a Bitmap (C++ Builder 6.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. |
On the Project pull-down menu, use the Import Type library… and install the LEAD Raster Process object library (14.5). Press OK. |
3. |
Select LEAD Raster Process from the ActiveX tab and add it to your form. |
4. |
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
5. |
Add a button to your form and name it as follows: |
|
|
Put it at the top of the form to keep it away from the image. |
|
|
Name |
Caption |
|
btnCropping |
Cropping |
6. |
Code the btnCropping 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::btnCroppingClick(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;
}
7. |
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;
}
8. |
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 = true;
}
}
9. |
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 = false;
LEADRasterView1->MousePointer = crDefault;
}
}
10. |
Add a button to your form. It 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, name it as follows: |
|
|
Name |
Caption |
|
btnTrim |
Trim |
11. |
Code the btnTrim 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::btnTrimClick(TObject *Sender)
{
float XFactor, YFactor;
float NewLeft, NewTop, NewWidth, NewHeight;
float HeightFactor, WidthFactor;
float HeightAllowed, WidthAllowed;
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.
LEADRasterProcess1->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)
{
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;
}
12. |
Run your program to test it. |