Using FreeImage to fit a PNG file in an image control

Thanks Mike. How do I write it back to the control?

  PROGRAM

  INCLUDE('gdiplus.inc'), ONCE

  MAP
  END

Window                        WINDOW('PNG image in C6'),AT(,,208,120),CENTER,GRAY,SYSTEM
                                IMAGE,AT(9,14,64,59),USE(?IMAGE1)
                              END

bm                            TGdiPlusBitmap
sBits                         &STRING, AUTO
  CODE
  OPEN(Window)
  
  bm.FromFile('CristmasTree.png')
!  bm.FromFile('c:\development\apps\winapi\GdiPlus\examples\Metadata\myphoto.jpg')
  sBits &= bm.ToString('image/bmp')
  ?IMAGE1{PROP:ImageBits} = sBits
  DISPOSE(sBits)
  
  ACCEPT
  END

Yes. I got that part to work. Now I need to scale and crop the bm to fit the IMAGE control.

Look at .\examples\Using Images\UsingImages.clw, ScaleCropImage procedure.

Hi Mike,

Yes. That is what I was looking at in terms of code. The problem is that in the example, it is not writing back to an IMAGE control. You are getting the handle of the window and then drawing it manually to the window. I have a lot of controls on the window and the image part resizes. I was hoping that I can manipulate the image and then send it to a Clarion IMAGE control and not have to do everything non-Clarion.

This is not true: I’m getting the handle of device context to create TGdiPlusGraphics object. In your case you should create TGdiPlusGraphics object over dest bitmap, draw what you want, then display the result in an image control.

Thank Mike. It is the displaying the result in the image control that I don’t get.

This I get.
sBits &= bm.ToString(‘image/bmp’)
?IMAGE1{PROP:ImageBits} = sBits
DISPOSE(sBits)

This I don’t get in getting it assigned to the IMAGE control.

  1. Load original bitmap: bm1.FromFile(‘image.png’)
  2. Create new bitmap: bm2.CreateBitmap(1000, 1000, format)
  3. Create Graphics object over bitmap2: g.FromImage(bm2)
  4. Draw 1 on 2: g.DrawImage(bm1, 0, 0, 1000, 1000)

Rename all your bm, bm1, bm2 etc into bmSrc and bmDst. Then:

  • load source image bmSrc
  • create destination image bmDst with desired size
  • create Graphics object g over bmDst
  • draw a part of source image on an area of dest image
  • display image bits of resulted dest image

I understand the concept of what you are saying, the problem in the example of .\examples\Using Images\UsingImages.clw, ScaleCropImage procedure, there is no writing back to a defined IMAGE for a WINDOW.

If I have

Window WINDOW('Part Groups'),AT(,,397,224),FONT('Segoe UI',9),RESIZE,CENTER,ICON('module.ico'),GRAY,IMM,MAX LIST,AT(4,4,194,218),USE(?TreeList),FORMAT('1020L(2)|MIT@s255@'),FROM(TV1::Queue),#FIELDS(m_Display),#ORDINAL(1) IMAGE,AT(202,4,191,204),USE(?Diagram_Image),CENTERED,#ORDINAL(3) BUTTON('Close'),AT(357,211,36,12),USE(?CloseButton),FONT('Segoe UI',9,,FONT:regular),#ORIG(?Close),#SEQ(1),#ORDINAL(2) END

I can

bm1.FromFile(PGP:DIAGRAM_IMAGE) sBits &= bm1.ToString('image/bmp') ?Diagram_Image{PROP:ImageBits} = sBits DISPOSE(sBits)

but how do I go about setting the ?Diagram_Image to the new graphics object.

?Diagram_Image{PROP:ImageBits} = ???

Here you display bm1 image. To display bm2 image, do the same:

sBits &= bm2.ToString(‘image/bmp’) ?Diagram_Image{PROP:ImageBits} = sBits DISPOSE(sBits)

Mike,

Thanks for your help.

bmSrc.FromFile(PGP:DIAGRAM_IMAGE) DO GetImageInformation bmDest.CreateBitmap(ImagePixelWidth, ImagePixelHeight, PixelFormat24bppRGB) g.FromImage(bmDest) g.DrawImage(bmSrc, ImagePixelXOffset,ImagePixelYOffset,ImagePixelWidth - ImagePixelXDiff,ImagePixelHeight - ImagePixelYDiff) sBits &= bmDest.ToString('image/bmp') ?Diagram_Image{PROP:ImageBits} = sBits DISPOSE(sBits)

When using

bmDest.CreateBitmap(ImagePixelWidth, ImagePixelHeight, PixelFormat24bppRGB)

is there anyway to set the bitmap to transparent or a specific colour?

Well, you can draw a rectangle using a solid brush of argb color.

I switched to a PixelFormat32bppRGB from PixelFormat24bppRGB which should have gotten the Alpha channel, but it doesn’t work when I use GdipMakeARGB(0, 255, 255, 255).

And I used g.GraphicsClear(GdipMakeARGB(255, 255, 255, 255))

Is there something in the code that is preventing the Alpha channel from being used for transparency?

  bmSrc.FromFile(PGP:DIAGRAM_IMAGE)
  DO GetImageInformation
  bmDest.CreateBitmap(ImagePixelWidth, ImagePixelHeight, PixelFormat32bppRGB)
  g.FromImage(bmDest)
  !brush.CreateSolidBrush(GdipMakeARGB(255, 255, 255, 255))
  !g.FillRectangle(brush,0,0,ImagePixelWidth,ImagePixelHeight)
  g.GraphicsClear(GdipMakeARGB(255, 255, 255, 255))
  g.DrawImage(bmSrc, ImagePixelXOffset,ImagePixelYOffset,ImagePixelWidth - 
  ImagePixelXDiff,ImagePixelHeight - ImagePixelYDiff)
  sBits &= bmDest.ToString('image/bmp')
  ?Diagram_Image{PROP:ImageBits} = sBits
  DISPOSE(sBits)

I know nothing about what you’re doing, but don’t you want to use the ARGB rendition of this? The place on the web page about PixelFormat32bppRGB, specifies that those 8 bits, normally used for alpha, are not used.

Thanks Jeff. I missed that.

bmDest.CreateBitmap(ImagePixelWidth, ImagePixelHeight, PixelFormat32bppARGB)
g.FromImage(bmDest)
g.GraphicsClear(GdipMakeARGB(0, 255, 255, 255))

Still makes a black background.

g.FromImage(bmDest)
g.GraphicsClear(GdipMakeARGB(1, 255, 255, 255))

This works.

I just added Show method to display an image in IMAGE control:
bm.Show(?Image1)

1 Like

I couldn’t find any equates for

g.Clear(Color.Transparent);

Does anyone know if GDI+ supports AVIF?

Does not support it.