2006-02-06

RESIZE IMAGES WITH VFP9 and GDI+

The function GetThumbnailImage can be used to get a resized image, but the result may come with less quality.

The sample below does the same thing, but creates an image with a better quality.

#DEFINE GdiPlus_PixelFormat_1BPPindexed      0x00030101
#DEFINE GdiPlus_PixelFormat_4BPPindexed      0x00030402
#DEFINE GdiPlus_PixelFormat_8BPPindexed      0x00030803
#DEFINE GdiPlus_PixelFormat_16BPPgrayscale   0x00101004
#DEFINE GdiPlus_PixelFormat_16BPPRGB555      0x00021005
#DEFINE GdiPlus_PixelFormat_16BPPRGB565      0x00021006
#DEFINE GdiPlus_PixelFormat_16BPPARGB1555    0x00061007
#DEFINE GdiPlus_PixelFormat_24BPPRGB         0x00021808
#DEFINE GdiPlus_PixelFormat_32BPPRGB         0x00022009
#DEFINE GdiPlus_PixelFormat_32BPPARGB        0x0026200a
#DEFINE GdiPlus_PixelFormat_32BPPpARGB       0x000e200b
#DEFINE GdiPlus_PixelFormat_48BPPRGB         0x0010300c
#DEFINE GdiPlus_PixelFormat_64BPPpARGB       0x001c400e

LOCAL lcSource, lcDestination
m.lcSource = GETPICT("jpg;gif;bmp")
m.lcDestination = ADDBS(JUSTPATH(m.lcSource)) + "resized_" + JUSTSTEM(m.lcSource) + ".bmp"

LOCAL loImage AS gpImage OF ffc / _GdiPlus.vcx
m.loImage = NEWOBJECT("gpimage", HOME() + "ffc/_GdiPlus.vcx")
m.loImage.CreateFromFile(m.lcSource)

LOCAL loBitmap AS gpBitmap OF ffc / _GdiPlus.vcx
m.loBitmap = NEWOBJECT("gpbitmap", HOME() + "ffc/_GdiPlus.vcx")

LOCAL loGraphics AS gpGraphics OF HOME() + ffc / _GdiPlus.vcx
m.loGraphics = NEWOBJECT('gpgraphics',HOME() + 'ffc/_GdiPlus.vcx')

*** now we create a new image with
*** create method - creates a bitmap object.
*** syntax: ? this.create(tnwidth, tnheight[, tnpixelFormat])
*** tnpixelFormat, optional, one of GdiPlus_pixelFormat_* constants,
*** defaults to GdiPlus_pixelFormat_32BPPARGB.

LOCAL lnNewWidth, lnNewHeight
m.lnNewWidth = 640  && put here the desired width
m.lnNewHeight = 480 && put here the desired height

m.loBitmap.CREATE(m.lnNewWidth, m.lnNewHeight, GdiPlus_PixelFormat_32BPPpARGB)
*** the other constants are in the beginning of this code

m.loGraphics.CreateFromImage(m.loBitmap)
m.loGraphics.DrawImageScaled(m.loImage, 0, 0, m.lnNewWidth, m.lnNewHeight)
m.loBitmap.SaveToFile(m.lcDestination, "image/bmp")

RETURN
 

Update 04/08/2007

 

Below is another way to resize an image using the GetThumbnailImage function, shown by Craig Boyd in a UT thread:

LOCAL lcSource, lcDestination
m.lcSource = GETPICT()
m.lcDestination = "c:\" + JUSTFNAME(m.lcSource) && image will be saved on to c:\</font>
IF ! CreateThumbnail(m.lcSource, m.lcDestination, 85, 100)
    MESSAGEBOX("unable to create image")
ENDIF

FUNCTION CreateThumbnail(tcsource, tcdestination, tnwidth, tnheight)
    LOCAL llSuccess, loImage, loThumbImage
    m.llSuccess = .F.
    IF FILE(m.tcsource)
        m.loImage = NEWOBJECT('gpimage',HOME(1) + 'ffc\_gdiplus.vcx')
        m.loImage.CreateFromFile(m.tcsource)
        m.loThumbImage = m.loImage.getthumbnailimage(m.tnwidth, m.tnheight)
        IF TYPE("lothumbimage") = "o"
            m.llSuccess = m.loThumbImage.SaveToFile(m.tcdestination, "image/jpeg")
        ENDIF
    ENDIF
    RETURN m.llSuccess
ENDFUNC

12 comments:

  1. That's really cool. Thank you Caesar.


    Just a simple bug. -:)

    instead of :

    lcDestination = "Resized_" + lcSource


    it works better with:

    lcDestination = ADDBS(JUSTPATH(lcSource))+"Resized_" + JUSTSTEM(lcSource)+".bmp"


    BTW, do you know how you can skew an image?

    ReplyDelete
  2. Hi Vassilis,

    Thanks very much for the feedback and fix.

    I've already fixed the code.


    What do you mean by "skew an image" ?

    Can you send me a link with an example ?

    Sorry for my bad english.

    I'm from Brazil.

    ReplyDelete
  3. Hi Cesar,


    Try : WinKey + R --> mspaint --> load an image and press Ctrl + W.

    You will see settings for the SKEW effect in the second group of textboxes.


    Thank you

    ReplyDelete
  4. Thanks,

    Yes, this can be done too.

    I'll try to post an example soon !

    Regards

    Cesar

    ReplyDelete
  5. Vassilis,

    Pls take a look at this link

    http://weblogs.foxite.com/cesarchalom/archive/2006/02/09/1132.aspx

    ReplyDelete
  6. Hi Cesar,


    the created pictures have a resolution of 96 dpi, but I need 72 dpi.

    How can I change it?


    Greetings from Bavaria


    Siegfried

    ReplyDelete
  7. Hi Cesar,
    Hi Alec,

    Thanks for the sample code. Very helpful for making thumbnails.  Two questions:

    #1 Is there a way to do this with a string of the image rather than working with files?  I am pulling the image from a database field and forwarding it via IP and it would seem that writing the image out to a file on disk will slow the process down considerably.
    YES, it is possible, and I hope to Blog about it soon. Anyway, the speed will depend on the quantity of strings you need to process. You can have a look at the Gdiplus-X classes too. Bo Durban has prepared some cool usages of images without disk access.

    #2 Is there a way to determine the size attributes of the source image so as to maintain the proper aspect ratio when thumbnailing it?  If Idon't know the height and width of the source image then arbitrarily changing it may (and most likely will )change the aspect ration and make the image apear funny...
    Yes, that's very easy too. Pls check this link: GETTING IMAGE PROPERTIES WITH GDI+
    Thanks
    Alec
    HTH
    Cesar

    ReplyDelete
  8. Hi Cesar,

    Greatpost. Thanks!

    When using the _gdiplus class is it possible to pass and receive an image as a variable rather than going to/from disk.  I want to pull image from a table and pass it to another program without having to go to disk to thumbnail the image. If so, how?

    Thanks

    Alec

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

    ReplyDelete
  10. Very Useful for me Thanks a lot.....

    ReplyDelete
  11. Hi Cesar, I am wanting to resize an image without losing too much quality. I currently use thumbnail but the result is very poor. I got excited when I saw this, especially when I saw it was you as I am familiar with the quality of your work. I have cut and paste this code - it asks for the file and produces no errors but also no file. I have tried
    LOCAL lcSource, lcDestination
    m.lcSource = GETPICT("jpg;gif;bmp")
    m.lcDestination = ADDBS(JUSTPATH(lcSource))+"Resized_" + JUSTSTEM(lcSource)+".jpg"

    and also the following as I would like a jpeg
    m.loBitmap.SaveToFile(m.lcDestination, "image/JPEG")

    ReplyDelete