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.