2006-05-25

CROP IMAGES WITH GDI+

Cropping an image is a simple task for Gdiplus.
One of the ways that this can be done is using the GDI+ function gdipclonebitmapareai , that unfortunately was not included in _Gdiplus.vcx, but can be easily accessed.

Original Image



Top Left

Center



Bottom Right


Run the code below, selecting any image, and you will see the image cropped in three ways: the top-left part of the image, the bottom-right part, and the center.

LOCAL lcSource
lcSource = GETPICT()

IF EMPTY(lcSource)
RETURN
ENDIF
* Load image to GDI+
LOCAL loImage AS gpImage OF HOME() + ffc/_gdiplus.vcx
loImage = NEWOBJECT("gpImage",HOME()+"ffc/_gdiplus.vcx")
loImage.CreateFromFile(lcSource)
lnWidth = loImage.ImageWidth
lnHeight = loImage.ImageHeight

* Crop Image LOCAL loCropped as gpBitmap OF HOME() + ffc/_gdiplus.vcx

* Crop TopLeft
loCropped = Crop(loImage, 0, 0, lnWidth / 2, lnHeight /2)
loCropped.SavetoFile("crop-topleft.png","image/png")
RUN /n Explorer.exe crop-topleft.png

* Crop BottomRight
loCropped = Crop(loImage, lnWidth / 2, lnHeight /2, lnWidth /2, lnHeight /2)
loCropped.SavetoFile("crop-bottomright.png","image/png")
RUN /n Explorer.exe crop-bottomright.png

* CropCenter
loCropped = Crop(loImage, lnWidth / 4, lnHeight /4, lnWidth /2, lnHeight /2)
loCropped.SavetoFile("crop-center.png","image/png")
RUN /n Explorer.exe crop-center.png

RETURN

PROCEDURE Crop(toImage, x, y, tnWidth, tnHeight, tnPixelFormat)
IF VARTYPE(tnPixelFormat) = "l"
   tnPixelFormat = toImage.PixelFormat
ENDIF 
* gpstatus wingdipapi gdipclonebitmapareai
* (int x, int y, int width, int height, pixelformat format,
* gpbitmap *srcbitmap, gpbitmap **dstbitmap)
DECLARE LONG gdipclonebitmapareai IN gdiplus.dll ;
   LONG x, LONG y, LONG nwidth, LONG nheight, ;
   LONG pixelformat, LONG srcbitmap, LONG @dstbitmap
LOCAL lnNewBitmap
lnNewBitmap = 0
= gdipCloneBitmapAreaI(x, y, tnWidth, tnHeight, ;
tnPixelFormat, toImage.getHandle(), @lnNewBitmap)
LOCAL loNewImage
loNewImage = NEWOBJECT("gpBitmap",HOME()+"ffc/_gdiplus.vcx")
loNewImage.SetHandle(lnNewBitmap)
RETURN lonewimage
ENDPROC 


To achieve this, I created a small procedure, "crop", that receives the following parameters retrieved from msdn :

    toimage - image or bitmap object

    x - integer that specifies the x-coordinate of the upper-left corner of the rectangle that specifies the portion of this bitmap to copy.

    y - integer that specifies the y-coordinate of the upper-left corner of the rectangle that specifies the portion of this bitmap to copy.

    width - integer that specifies the width of the rectangle that specifies the portion of this bitmap to copy.

    height - integer that specifies the height of the rectangle that specifies the portion of this image to copy.

    format - optional, integer that specifies the pixel format of the new bitmap. the pixelformat data type and constants that represent various pixel formats are defined in gdiplus.h. for more information about pixel format constants, see image pixel format constants.

    return - this method returns a pointer to the new bitmap object containing the cropped image.

3 comments:

  1. Cesar!


    Imagine my surprise when logged into Foxite tonight! :)


    As you know, I've often wondered how cropping could be done in VFP.


    Your Crop() function makes it a cake walk!


    Thank you!!!


    Malcolm

    ReplyDelete
  2. Versión en Español de este artículo en / Spanish version at http://www.portalfox.com/article.php?sid=2223    

    ReplyDelete
  3. Wonderful!


    I am using third party tool to do this image cropping.

    Now it is possible to do this in VFP itself!


    Good work Cesar, and thank you very much for sharing your work !!


    Kishore

    ReplyDelete