Convert image format and size with gdiplusX & APIs

Published on by Yousfi Benameur


I remarked i dont gave a gdiplusX code to convert any picture from one format to another explicitly in my previous codes.
this one converts any image to PNG,JPG,BMP ,GIF,ICO (can add other supported gdiplusX format-see below-).
the image converted can be resized as the user wants with preserving ratio or not.
the preserving ratio provides always to the picture a good readability.its the original width/height fraction multiplied by the new height.
in each image format the code applies the gdiplusX specific encoder (PNG,JPEG,BMP,GIF,ICON...)
the image is saved in original folder source as yconverted+extension ...


 the xfcImageFormat might be
BaseName = "ImageFormat"
Bmp 	&& Gets the bitmap image format (BMP).
Emf 	&& Gets the enhanced Windows metafile image format (EMF).
Exif 	&& Gets the Exchangeable Image File (Exif) format.
Gif 	&& Gets the Graphics Interchange Format (GIF) image format.
Guid 	&& Gets a Guid structure that represents this ImageFormat object.
Icon 	&& Gets the Windows icon image format.
Jpeg 	&& Gets the Joint Photographic Experts Group (JPEG) image format.
MemoryBmp 	&& Gets a memory bitmap image format.
Png 	&& Gets the W3C Portable Network Graphics (PNG) image format.
Tiff 	&& Gets the Tag Image File Format (TIFF) image format.
Wmf 	&& Gets the Windows metafile (WMF) image format.

Important:you can also convert any picture to icon with the pointed encoder as:
loBMP1.save(m.lcdest,.imaging.imageformat.ICON)
or an Icon to any image format .Note that Icon dimensions are standard(16x16,32x32,64x64,96x96,128x128)
Warning:the icon produced is with  depth=8 (poor).A normal icon have depth=32 !


the code (saved as prg) does the same thing that the copyImage API does and shown in previous posts (see the link at bottom of page).
the code asks to system.app location to load it before working.


Click on code to select [then copy] -click outside to deselect

*1*
*convert and resize any picture with gdiplusX with preserving Ratio or no

Local m.yrep
m.yrep=Addbs(Justpath(Sys(16,1)))

Do Locfile("system.app","app")

Local m.xpict
m.xpict=Getpict()
If Empty(m.xpict)
    Return .F.
Endi
Local m.oo,mw0,m.h
m.oo=Newobject("image")   &&get original dimensions of this image (native vfp)
m.oo.Picture=m.xpict
m.w0=m.oo.Width
m.h0=m.oo.Height
m.oo=Null


Local m.x
m.x=Inputbox("SAve as: PNG,JPG,BMP,GIF,ICO","","PNG")   &&convert to...
If Empty(m.x) Or !Inlist(Upper(m.x),"PNG","JPG","BMP","GIF","ICO")
	Return .F.
Endi
m.x=Upper(m.x)

Local xdim
m.xdim=Inputbox("format Widthxheight","","640x480")   &&resize to this format wxh
m.xdim=lower(m.xdim)
Local m.w,m.h
If Empty(m.xdim) Or !"x"$ m.xdim
    m.w=m.W0
    m.h=m.h0
Else   &&extract wanted dimensions of the converted image
	m.w=Strextract(m.xdim,'',"x")
	m.h=Strextract(m.xdim,"x","")
Endi



Local m.preserveRatio
m.preserveRatio=Inputbox("preserve ratio image ? : yes -no","","no")
If Empty(m.preserveRatio) Or !Inlist(Lower(m.preserveRatio),"yes","no")
	m.preserveRatio="no"
Endi

m.w=Int(Val(m.w))
m.h=Int(Val(m.h))

If m.preserveRatio="yes"
	m.h=Int(m.h*m.w0/m.h0)
Endi

If m.w=0 Or m.h=0
	Return .F.
Endi

Local loBMP,loBMP1 As fxcBitmap

With _Screen.System.drawing
	loBMP=.Image.fromfile(m.xpict)

	Local  m.lcdest
	m.lcdest=m.yrep+"yconverted"+"."+m.x

	loBMP1=.Bitmap.new(m.w,m.h)
	logfx= .Graphics.FromImage(loBMP1)
    &&working with smoothless & high quality drawing
    LOGFX.smoothingmode     = .drawing2d.smoothingmode.highquality
    LOGFX.interpolationmode = .drawing2d.interpolationmode.highqualitybicubic
    LOGFX.pixeloffsetmode   = .drawing2d.pixeloffsetmode.highquality
	logfx.Clear(.Color.white)
	logfx.drawImage(loBMP,0,0,m.w,m.h)

	Do Case
		Case m.x=="PNG"
loBMP1.Save(m.lcdest,.imaging.imageformat.PNG)
		Case m.x=="JPG"
loBMP1.Save(m.lcdest,.imaging.imageformat.JPEG)
		Case m.x=="BMP"
loBMP1.Save(m.lcdest,.imaging.imageformat.BMP)
		Case m.x=="GIF"
loBMP1.Save(m.lcdest,.imaging.imageformat.GIF)
            Case m.x=="ICO"
loBMP1.Save(m.lcdest,.imaging.imageformat.ICON)    
	Endcase

Endwith

Run/N explorer &lcdest  &&show the converted/resized image with explorer
retu

 

can convert the code above as a form when can set all parameters and starts the conversion...can also crop original  image to a specifc area...

can convert the code above as a form when can set all parameters and starts the conversion...can also crop original image to a specifc area...

Click on code to select [then copy] -click outside to deselect

*2* created on 25 of december 2016
*this code use gdiplusX to convert any image (silently) to any format (PNG,JPG,BMP,GIF,EMF)
*it dont draw with xfcgraphic as code *1*
*it dont uses form support but _screen and it can be not visible.
*(can use also the imgcanvas.oBMP property to save)

_Screen.Visible=.F.
Do Locfile('system.app')   &&put it in c:\windows\system32 (or in source folder) to dont have asked all time.
Local m.yrep
m.yrep=Addbs(Justpath(Sys(16,1)))
Set Defa To (yrep)

Set Classlib To Locfile("gdiplusx","vcx") AddI  &&can hard code the gdiplusX location here
_Screen.AddObject("yimgcanvas",'imgcanvas')


With _Screen.yimgcanvas
	.drawWhenInvisible=.T.
	.Name="yimgcanvas"
	.Visible=.T.
Endwith

With _Screen.System.drawing
	Local loBmp As xfcBitmap
	loBmp=.Bitmap.fromfile(Getpict())
	Local m.xext
	m.xext=Inputbox("Convert to PNG,JPG,BMP,GIF,EMF","","PNG")
	If !Inlist(Upper(m.xext),"PNG","BMP","JPG","GIF","EMF")
		m.xext="PNG"
	Endi

	Local m.lcdest
	m.lcdest=m.yrep+"ycaptured"+Sys(2015)+"."+m.xext
	*messagebox(m.lcdest)

	Do Case
		Case Justext(m.lcdest)="JPG"
			loBmp.Save(m.lcdest,.imaging.imageformat.JPEG)
		Case Justext(m.lcdest)="PNG"
			loBmp.Save(m.lcdest,.imaging.imageformat.PNG)
		Case Justext(m.lcdest)="BMP"
			loBmp.Save(m.lcdest,.imaging.imageformat.BMP)
		Case Justext(m.lcdest)="GIF"
			loBmp.Save(m.lcdest,.imaging.imageformat.GIF)
		Case Justext(m.lcdest)="EMF"
			loBmp.Save(m.lcdest,.imaging.imageformat.EMF)
	Endcase

Endwith

Try
	_Screen.RemoveObject("yIMGcanvas")
Catch
Endtry

Release Classlib gdiplusX
_Screen.Visible=.T.

Run/N explorer &lcdest




Click on code to select [then copy] -click outside to deselect


*3* created on saturday 18 of february 2018
*convert any picture to JPG,PNG,BMP,GIF with pure gdiplus APIs using standard encoders for each format.

Clea All

Set Defa To Addbs(Justpath(Sys(16,1)))
Do ydeclare
*gdiplus encoders
#Define BMPClsID 0h00F47C55041AD3119A730000F81EF32E &&BMP Format
#Define JPGClsID 0h01F47C55041AD3119A730000F81EF32E &&JPG Format
#Define GIFClsID 0h02F47C55041AD3119A730000F81EF32E &&GIF Format
#Define TIFClsID 0h05F47C55041AD3119A730000F81EF32E &&TIF Format
#Define PNGClsID 0h06F47C55041AD3119A730000F81EF32E &&PNG Format

Local xpict,tbuffer,hGraphic
m.xpict=Getpict()
If Empty(m.xpict)
  Return .F.
Endi
tbuffer = 0
=GdipLoadImageFromFile(Strconv(m.xpict+Chr(0), 5), @tbuffer)
hGraphic = 0
=GdipGetImageGraphicsContext(tbuffer, @hGraphic)
=GdipDeleteGraphics(hGraphic)

Local m.lcfile0,m.lcfile
m.lcfile = Putfile("Save to ", "picture", "jpg|png|gif|bmp")
If Empty(m.lcfile)
  Return .F.
Endi

Local m.lcEncoder
Do Case
  Case Lower(Justext(m.lcfile))=="png"
    m.lcEncoder=PNGClsID
  Case Lower(Justext(m.lcfile))=="jpg"
    m.lcEncoder=JPGClsID
  Case Lower(Justext(m.lcfile))=="gif"
    m.lcEncoder=GIFClsID
  Case Lower(Justext(m.lcfile))=="bmp"
    m.lcEncoder=BMPClsID
Endcase
m.lcfile0=m.lcfile
m.lcfile = Strconv(m.lcfile + Chr(0), 5)

=gdipSaveImageToFile(tbuffer, m.lcfile,m.lcEncoder, Null)

Run/N explorer &lcfile0
Clea Dlls
Retu

Procedure ydeclare
  Declare Long GdipLoadImageFromFile In GDIPlus.Dll String, Long @
  Declare Long GdipGetImageGraphicsContext In GDIPlus.Dll Long nativeImage, Long @ graphics
  Declare GdipDeleteGraphics In GDIPlus.Dll Long
  Declare Long GdipSaveImageToFile In GDIPlus.Dll Long, String, String, String
Endproc


Click on code to select [then copy] -click outside to deselect



*4* created on Friday  16 of march 2018
*convert a complet folder of images with any initial format(jpg,png,bmp,gif) to another format with same dimensions
*Initaial  pictures converted to one format : to JPG,PNG,BMP,GIF with pure gdiplus APIs using standard encoders for each format.
*a new folder gathering the converted images is created in source folder as "converted\"

Clea All
local m.yrep0
m.yrep0=Addbs(Justpath(Sys(16,1)))
Set Defa To (yrep0)
if !directory (m.yrep0+"converted")
md (m.yrep0+"converted")
endi

Do ydeclare

local m.yrep
m.yrep=getd("","","",32)
if empty(m.yrep)
return .f.
endi
m.yrep=addbs(m.yrep)

local gnbre
gnbre=adir(gabase,m.yrep+"*.*")
create cursor ycurs (xfilename c(240))
for i=1 to gnbre
if inlist( lower( justext(m.yrep+gabase(i,1))),"bmp","jpg","png","gif")
insert into ycurs values (m.yrep+gabase(i,1))
endi
endfor
brow nowait

m.xformatCible=inputbox("convert images to PNG,JPG,BMP,GIF","","JPG")
if empty(m.xformatCible) or !inlist(lower(m.xformatCible),"jpg","png","bmp","gif")
m.xformatCible="JPG"
endi

scan
=yconvert(xfilename,m.yrep0+"converted\"+juststem(xfilename)+"."+m.xformatCible)
endscan
Clea Dlls

local m.oo
m.oo=m.yrep0+"converted"
Run/N explorer &oo
Retu

function yconvert
lparameters xfilename,lcdestination
*gdiplus encoders
#Define BMPClsID 0h00F47C55041AD3119A730000F81EF32E &&BMP Format
#Define JPGClsID 0h01F47C55041AD3119A730000F81EF32E &&JPG Format
#Define GIFClsID 0h02F47C55041AD3119A730000F81EF32E &&GIF Format
#Define TIFClsID 0h05F47C55041AD3119A730000F81EF32E &&TIF Format
#Define PNGClsID 0h06F47C55041AD3119A730000F81EF32E &&PNG Format

Local tbuffer,hGraphic
tbuffer = 0
=GdipLoadImageFromFile(Strconv(xfilename+Chr(0), 5), @tbuffer)
hGraphic = 0
=GdipGetImageGraphicsContext(tbuffer, @hGraphic)
=GdipDeleteGraphics(hGraphic)

Local m.lcEncoder
Do Case
  Case Lower(Justext(m.lcdestination))=="png"
    m.lcEncoder=PNGClsID
  Case Lower(Justext(m.lcdestination))=="jpg"
    m.lcEncoder=JPGClsID
  Case Lower(Justext(m.lcdestination))=="gif"
    m.lcEncoder=GIFClsID
  Case Lower(Justext(m.lcdestination))=="bmp"
    m.lcEncoder=BMPClsID
Endcase
m.lcdestination0=lcdestination
m.lcdestination = Strconv(m.lcdestination + Chr(0), 5)

=gdipSaveImageToFile(tbuffer, m.lcdestination,m.lcEncoder, Null)
wait window m.lcdestination0  nowait
endfunc

Procedure ydeclare
  Declare Long GdipLoadImageFromFile In GDIPlus.Dll String, Long @
  Declare Long GdipGetImageGraphicsContext In GDIPlus.Dll Long nativeImage, Long @ graphics
  Declare GdipDeleteGraphics In GDIPlus.Dll Long
  Declare Long GdipSaveImageToFile In GDIPlus.Dll Long, String, String, String
Endproc


To be informed of the latest articles, subscribe:
Comment on this post