the vfp image base class now has the rotateflip property where the image set as the picture property can be rotated and/or flipped.

the different states for the vfp control are:

0 - rotate0flipnone

1 - rotate90flipnone

2 - rotate180flipnone

3 - rotate270flipnone

4 - rotatenoneflipx

5 - rotate90flipx

6 - rotate180flipx

7 - rotate270flipx

(funnily enough these are exactly the same enumerations in the gdi+x classes.smile [:)])

however the image base class has a problem. it cannot show an image background as transparent if the rotateflip property is anything other than 0. this can esaily be illustrated in this images below, where the image control has backstyle = 0 transparent

when the rotateflip is changed to non 0 the background is no longer transparent, even at runtime and this is a big failing.

to the rescue comes the gdi+x classes. since this is an image control, all image properties are available that you usually set - picture, backstyle, stretch, rotateflip etc.

with just a few lines of code inserted in the gdi+x imgcanvas class we can make sure that our backstyle setting is respected by the image class at runtime even if the rotateflip property is non 0.

the attached file (link at bottom) contains this class that will do this for you. all you need to do is drop it on a form, set the normal properties you would set, set a custom property as i will show later on and when the form is run, the image will respect your settings.

in the image below the class is dropped on a form along with normal vfp image base classes. all these objects have the rotateflip set to 2 - rotate180flipnone.

as you can see the controls do not respect the backstyle property which has been set to 0 - transparent when the rotateflip has been changed and this persists even at runtime.

to the left above are two instances of my class and to the right, two instances of the vfp base image class. there are two bmp's involved, one with a white background and the other with a majenta (rgb(255,0,255) background.

the only properties that need setting, i have added to the favourites tab. i have also added some memberdata code to the transparentcolour property to allow selection from the vfp colour selector, since an integer colour is needed here. click on the property and then the button that will appear to change the colour.

the transparentcolour property is the colour that you want to make invisible. in the image on the left it is white and in the image on the right it is majenta.

the default for the class is white as shown below:

the image on the right has been changed as shown below, using the button provided.

the result, at runtime is that while the vfp baseclasses do not handle the backstyle property at all when rotateflip is non 0, the gdi+x class with the addition of my code does this very well.

i have barely scratched the surface of these classes. there is scope for many, many improvements for enhancing the functionality of the lowly vfp image base class.

but hold on - there's more. there is one added benefit that this class brings and that again has to do with the backstyle property of the vfp image class. with the vfp base class, if backstyle was set to 0 - transparent, then any pixel of the image that was white (rgb(255,255,255) ) was made completely transparent. a number of images from the web use another colour to signify the transparent colour. so images with colour other than white as background, would not work since you are restricted to white only, with the base class.

in the form below, the same image is assigned to the vfp base image class on the left and my enhanced class on the right. the backstyle of both are set to 0 - transparent. as you can see the backcolour for this image we want to be invisible is magenta - rgb(255,0,255)

note that i have changed the transparentcolour property of my class  to 16711935 which is the majenta colour.

at runtime my class does it's work and makes any pixel of the image with that colour transparent as you can see below.

now that's 2 for the price of one by any reckoning.big smile [:d]

note:

as mentioned in other posts,

i dont include the gdiplusc.vcx since you need to download the latest from the vfpx site.

just open the form in vfp and when it asks you for the imgcanvas navigate it to the gdiplusx.vcx on your computer. the form will then resolve the location correctly. save the form, set the default path to the directory where the form is (to find the images) and then run the form. i have subclassed the imgcanvas class from the gdiplusx.vcx class library. unfortunately this would happen since i don't supply the gdiplusx.vcx and i don't know where a user might have stored it.

any ideas for further improvement are most welcome.

unfortunately because of the amount of junk mail being generated from the weblog i have switched off comments. please post your comments, if any, at www.foxite.com

3 Responses to Improving the VFP Image class with GDI+

  • Cesar says:

    Hi Bernard,

    The RotateFlip has also some other issues, like if you want to have the same image in a form rotated and another at the default normal rotation.

    I’ve been using a similar technique for this since some 2 years, and it works great !

    For your control, you still need to manage the Stretch property, dealing with the Clip, Isometric and Stretch possibilities. I’ve done this already, and hope to give that code a kind of treatment to work in your class and will pass to you.
    I know. That is why this is V1.

    For getting the needed transparent color, I have another property – “AutomaticTransparent”, set to TRUE. All it does is to obtain the color from the pixel from the coordinate (0,0) of the bitmap and make it transparent. You can get the color of the pixel using the xfcBitmap.GetPixel function.

    To have this, you could change your code in the BeforeDraw to the following:

    If Not Empty(This.originalimage)
    Local loGfx As xfcGraphics, oBmp As xfcBitmap
    With _Screen.System.Drawing
    oBmp = .Bitmap.New(This.originalimage)
    If This.BackStyle = 0

    LOCAL loColor as xfcColor
    IF This.AutomaticTransparent
      loColor = oBmp.GetPixel(0,0)
    ELSE
      loColor = .Color.FromRGB(This.TransparentColour)
    ENDIF
    oBmp.MakeTransparent(loColor)
    Endif
    loGfx = This.oGfx
    loGfx.InterpolationMode = .Drawing2D.InterpolationMode.HighQualityBicubic
    loGfx.Clear(.Color.Transparent)
    loGfx.DrawImage(oBmp, This.Rectangle)
    Endwith
    Endif

    Regards

    Cesar

    Thanks for the code Cesar. Basically I wanted to construct an image control that worked as I wanted it to rather that wrongly as it does now.

  • Norman says:

    It’s good
    i tried it and it’s working.
    I also try to make improvement so image streches when form to be resized. But i can’t succeed.
    Have any solution ? Plz share with me….

    All you have to do is set the Anchor property = 15. Then the image will resize automatically when th eform is resized. No changes to the class are needed. The only changes that are needed is as Cesar mentions in his post. I have set the STRETCH=2 as a default. If you need STRETCH=0 or 1 then implement Cesar’s code sample.

  • Norman says:

    Thanks Bernard.. It’s work..

Leave a Reply

Your email address will not be published. Required fields are marked *