Cropping a Bitmap (C++ 5.0 and later)
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. |
Go to the Project WorkSpace and click the FileView tab. |
3. |
Edit TUTORDLG.H and insert the following lines in the definition of CTutorDlg after DECLARE_MESSAGE_MAP(): |
BOOL m_bCropping; //The state when the mouse is used for cropping
float m_fStartX; //Starting X position in screen pixels
float m_fStartY; //Starting Y position in screen pixels
float m_fEndX; //Ending X position in screen pixels
float m_fEndY; //Ending Y position in screen pixels
4. |
Go to the Project Workspace and click the ResourceView tab. |
|
5. |
Double-click Dialog and double-click IDD_TUTOR_DIALOG to bring up the application's dialog box. |
|
6. |
Add a new button to use for activating a selection mode. To do this, select the button control on the Controls toolbar. Then, click and drag to position the button on the dialog box. |
|
7. |
Double-click the button and change IDC_BUTTON1 to IDC_SELECT. Also, set the Caption to &Select. |
|
8. |
Add another button to use for trimming the bitmap. To do this, select the button control on the Controls toolbar. Then, click and drag to position the button on the dialog box. |
|
9. |
Double-click the button and change IDC_BUTTON1 to IDC_TRIM. Also, set the Caption to &Trim. |
|
10. |
Press Ctrl-F4 to close all windows back to the Project Workspace. |
|
11. |
Start the Class Wizard and add code for the Select button. To do so, press Ctrl-W to go to the MFC Class Wizard; then do the following: |
|
|
a. |
Click the Message Maps tab. |
|
b. |
In the Class Name combo box, select CTutorDlg. |
|
c. |
In the Object IDs list box, select IDC_SELECT. |
|
d. |
In the Messages list box, select BN_CLICKED. |
|
e. |
Click the Add function button. Choose OK for the default function name (OnSelect). |
|
f. |
Click the Edit Code button to start entering the code. |
12. |
Enter new code as follows: |
void CTutorDlg::OnSelect()
{
// TODO: Add your control notification handler code here
// Initialize cropping so that you can do it more than once
if( m_bCropping )
{
// Set the clipping area to match the image.
m_LEADRasterView1.SetDstClipRect( m_LEADRasterView1.GetDstLeft(),
m_LEADRasterView1.GetDstTop(),
m_LEADRasterView1.GetDstWidth(),
m_LEADRasterView1.GetDstHeight() );
// Display the image
m_LEADRasterView1.ForceRepaint();
}
// Set a global variable to let other events know that you are cropping
m_bCropping = TRUE;
// Set the pointer to a crosshair
m_LEADRasterView1.SetMousePointer(2);
}
13. |
Add code for the Trim button. To do so, press Ctrl-W to go to the MFC Class Wizard; then do the following: |
|
|
a. |
In the Class name combo box, select CTutorDlg. |
|
b. |
In the Object IDs list box, select IDC_TRIM. |
|
c. |
In the Messages list box, select BN_CLICKED. |
|
d. |
Click the Add function button. Choose OK for the default function name (OnTrim). |
|
e. |
Click the Edit Code button to start entering the code. |
14. |
Enter new code as follows: |
void CTutorDlg::OnTrim()
{
float XFactor, YFactor,
NewTop, NewLeft, NewWidth, NewHeight;
ILEADRasterProcess *pRasterProc=NULL;
CoCreateInstance(CLSID_LEADRasterProcess, NULL, CLSCTX_ALL,
IID_ILEADRasterProcess, (void**)&pRasterProc);
// TODO: Add your control notification handler code here
m_LEADRasterView1.SetMousePointer(11); // hourglass
// 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 = m_LEADRasterView1.GetRaster().GetBitmapWidth() / m_LEADRasterView1.GetDstWidth();
YFactor = m_LEADRasterView1.GetRaster().GetBitmapHeight() / m_LEADRasterView1.GetDstHeight();
NewTop = (m_LEADRasterView1.GetDstClipTop() - m_LEADRasterView1.GetDstTop()) * YFactor;
NewLeft = (m_LEADRasterView1.GetDstClipLeft() - m_LEADRasterView1.GetDstLeft()) * XFactor;
NewWidth = m_LEADRasterView1.GetDstClipWidth() * XFactor;
NewHeight = m_LEADRasterView1.GetDstClipHeight() * YFactor;
// Make sure display rectangles are automatically adjusted.
m_LEADRasterView1.SetAutoSetRects(TRUE);
// Trim the bitmap. This changes the size of the image and
// both the source and destination clipping rectangles
pRasterProc->Trim(m_LEADRasterView1.GetRaster(), NewLeft, NewTop, NewWidth, NewHeight);
pRasterProc->Release();
// Turn off scroll bars to make sure we use the full client area.
m_LEADRasterView1.SetAutoScroll(FALSE);
// Set the image display size to match the LEAD control
// The source rectangle matches the smaller bitmap.
// Making the destination rectangle bigger, the paint will fill the LEAD control
m_LEADRasterView1.SetDstRect(0.0f, 0.0f, m_LEADRasterView1.GetScaleWidth(), m_LEADRasterView1.GetScaleHeight() );
m_LEADRasterView1.SetDstClipRect( 0.0f, 0.0f, m_LEADRasterView1.GetScaleWidth(), m_LEADRasterView1.GetScaleHeight() );
// Display the image
m_LEADRasterView1.ForceRepaint();
m_LEADRasterView1.SetMousePointer(0); // Default
}
15. |
To add the code for LEAD mouse events, do the following: |
|
|
a. |
Press Ctrl-W to go to the MFC ClassWizard. |
|
b. |
In the Class Name combo box, select CTutorDlg. |
|
c. |
In the Object IDs list box, select IDC_LEADRASTERVIEW1. |
|
d. |
Continue with the remaining steps for each mouse event. |
16. |
In the MFC ClassWizard, double-click the MouseDown event and add code as follows: |
void CTutorDlg::OnMouseDownLeadrasterview1(short Button, short Shift, float x, float y)
{
// Save the starting position
if( m_bCropping && Button == 1 )
{
m_fStartX = x;
m_fStartY = y;
// Make the rubberband invisible until the mouse moves
m_LEADRasterView1.SetRubberBandVisible(FALSE);
}
}
17. |
In the MFC ClassWizard, double-click the MouseMove event and add code as follows: |
void CTutorDlg::OnMouseMoveLeadrasterview1(short Button, short Shift, float x, float y)
{
if( m_bCropping && Button == 1 )
{
float rbX, rbY, rbWidth, rbHeight;
// Get the current mouse position
m_fEndX = x;
m_fEndY = y;
// Determine the origin of the rubberband rectangle,
// regardless of which way the mouse moves.
if( m_fEndX > m_fStartX )
rbX = m_fStartX;
else
rbX = m_fEndX;
if( m_fEndY > m_fStartY )
rbY = m_fStartY;
else
rbY = m_fEndY;
// Determine the height and width of the rubberband rectangle
rbHeight = (float)fabs((double)m_fStartY - m_fEndY);
rbWidth = (float)fabs((double)m_fStartX - m_fEndX);
// Set the rubberband rectangle
m_LEADRasterView1.SetRubberBandRect( rbX, rbY, rbWidth, rbHeight );
// Alternatively, you could use the following properties to set the
// rubberband rectangle:
// m_LEADRasterView1.SetRubberBandHeight(rbHeight);
// m_LEADRasterView1.SetRubberBandLeft(rbX);
// m_LEADRasterView1.SetRubberBandTop(rbY);
// m_LEADRasterView1.SetRubberBandWidth(rbWidth);
// Make the rubberband rectangle visible
m_LEADRasterView1.SetRubberBandVisible(TRUE);
}
}
18. |
In the MFC ClassWizard, double-click the MouseUp event and add code as follows: |
void CTutorDlg::OnMouseUpLeadrasterview1(short Button, short Shift, float x, float y)
{
if( m_bCropping && Button == 1 )
{
float CropLeft, CropTop, CropWidth, CropHeight;
// Get the current mouse position
m_fEndX = x;
m_fEndY = y;
// Get the origin of the clipping rectangle.
// Allow for different mouse drag directions
if( m_fStartX < m_fEndX )
CropLeft = m_fStartX;
else
CropLeft = m_fEndX;
if( m_fStartY < m_fEndY )
CropTop = m_fStartY;
else
CropTop = m_fEndY;
// Get the height and width of the cropped area
CropWidth = (float)fabs((double)m_fEndX - m_fStartX);
CropHeight = (float)fabs((double)m_fEndY - m_fStartY);
// Crop and repaint the image
m_LEADRasterView1.SetDstClipRect(CropLeft, CropTop, CropWidth, CropHeight);
m_LEADRasterView1.ForceRepaint();
m_LEADRasterView1.SetRubberBandVisible(FALSE);
m_LEADRasterView1.SetMousePointer(0); // Default
}
}
19. |
Press Ctrl-Home to go to the top of the current file (tutorDlg.cpp), and add the following to the list of include files: |
#include <math.h>
20. |
Rebuild and run the application. |