This page contains two demos that use Windows GDI+ to load images in several file formats.
GDIPlus functions require Windows XP or Windows 2000 Professional or Windows 2000 Server.This code was inspired by Dan Teel's GDIPlus example. Thanks, Dan.
No third-party DLL is needed to load images in the following formats: BMP, JPG/JPEG, PNG, TIFF, ICO, GIF
'GDIPlus functions require Windows XP or Windows 2000 Professional or Windows 2000 Server
'Code inspired by Dan Teel's GDIPlus example. Thanks, Dan.
'No third-party DLL is needed to load images in the following formats:
'BMP, JPG/JPEG, PNG, TIFF, ICO, GIF
nomainwin
UpperLeftX=5:UpperLeftY=5
WindowWidth=800:WindowHeight=500
menu #1, "&File", "&Open", [doOpen], "E&xit", [quit]
graphicbox #1.g, 0, 0, 790, 435
open "GDIPlus Image Loading" for window_nf as #1
#1.g "horizscrollbar on 0 3000; vertscrollbar on 0 2000"
#1.g "down; fill 255 240 200; flush mainSegment"
#1 "trapclose [quit]"
wait
[doOpen]
filedialog "Open Image File","*.jpg;*.png;*.tiff;*.ico;*.bmp;*.gif",imgfile$
if imgfile$="" then
notice "No image file chosen."
wait
else
hBitmap=GDIPlusLoadImage(imgfile$)
if hBitmap<>0 then
loadbmp "image",hBitmap
#1.g "delsegment mainSegment; discard" 'remove graphics from memory
#1.g "fill 255 240 200"
#1.g "drawbmp image 0 0;flush mainSegment"
unloadbmp "image"
'Remove from memory
calldll #gdi32,"DeleteObject",hBitmap as ulong, ret as ulong
else
notice "Unable to load image file!"
end if
end if
wait
[quit] close #1 : end
'*********************************
'You do not need to understand the two functions that follow.
'Paste them at the bottom of your code, and call the image-loading
'function like this:
' hBitmap=GDIPlusLoadImage(imgfile$)
'You may then use Liberty BASIC's LOADBMP function to load the image.
' loadbmp "image",hBitmap
'Draw it in a graphicbox or graphics window with LB's DRAWBMP statement.
'*********************************
function GDIPlusLoadImage(file$)
open "gdiplus.dll" for dll as #gdiplus
'this struct will be filled by API functions
STRUCT GDITOKEN, token as ulong
'we MUST fill this struct with GdiPlusVersion number
STRUCT GdiplusStartupInput,_
GdiplusVersion as ulong,_
DebugEventCallback as ulong,_
SuppressBackgroundThread as long,_
SuppressExternalCodecs as long
GdiplusStartupInput.GdiplusVersion.struct=1 'must be = 1
calldll #gdiplus,"GdiplusStartup",_
GDITOKEN as struct,_
GdiplusStartupInput as struct,_
status as ulong 'returns zero if successful
token=GDITOKEN.token.struct
if status<>0 then
GDIPlusLoadImage=0
else
wFile$=MultiByteToWideChar$(file$)
calldll #gdiplus,"GdipCreateBitmapFromFile", _
wFile$ as ptr,_ 'filename string in unicode (wide) character format
GDITOKEN as struct,_
status as ulong 'returns zero if successful
hBmpGdip=GDITOKEN.token.struct 'GDI+ bitmap returned in struct
if status<>0 then
GDIPlusLoadImage=0
else
'create GDI bitmap handle from GDI+ bitmap
calldll #gdiplus,"GdipCreateHBITMAPFromBitmap", _
hBmpGdip as ulong,_ 'GDIPlus bitmap
GDITOKEN as struct,_ 'bitmap handle will be returned in this struct
0 as ulong,_
status as ulong 'returns zero if successful
if status<>0 then
GDIPlusLoadImage=0
else
'get a bitmap handle we can use with Liberty BASIC's LOADBMP
GDIPlusLoadImage=GDITOKEN.token.struct
end if
calldll #gdiplus,"GdipDisposeImage",_ 'remove GDI+ bitmap
hImage as ulong,_ 'GDI+ bitmap handle
result as ulong
end if
calldll #gdiplus,"GdiplusShutdown",_ 'you must call this when finished
token as ulong,_ 'Token returned by a previous call to GdiplusStartup.
result as void 'no return from this function
close #gdiplus
end if
end function
function MultiByteToWideChar$(String$)
'converts any string into unicode
CodePage = 0 : dwFlags = 0 : cchMultiByte = -1
lpMultiByteStr$ = String$ : cchWideChar = len(String$) * 3
lpWideCharStr$ = space$(cchWideChar)
calldll #kernel32, "MultiByteToWideChar", _
CodePage as ulong, _ 'CP_ACP=0, ansi code page
dwFlags as ulong, _ 'use 0, flags for character translation
lpMultiByteStr$ as ptr,_'the ascii string to convert
cchMultiByte as long, _ 'len of string, -1 for null-terminated string
lpWideCharStr$ as ptr, _'buffer for returned ansi string
cchWideChar as long, _ 'size in wide characters of string buffer
result as long 'returns number of wide characters written to buffer
if result = 0 then
MultiByteToWideChar$ = ""
else
MultiByteToWideChar$ = left$(lpWideCharStr$, result * 2)
end if
end function
'GDIPlus functions require Windows XP or Windows 2000 Professional or Windows 2000 Server
'Code inspired by Dan Teel's GDIPlus example. Thanks, Dan.
'No third-party DLL is needed to load images in the following formats:
'BMP, JPG/JPEG, PNG, TIFF, ICO, GIF
'This extended demo adds ability to get image dimensions
'and resize graphicbox and/or scrollbars, as well as
'the ability to save as bmp.
nomainwin
UpperLeftX=5:UpperLeftY=5
WindowWidth=800:WindowHeight=500
gboxMaxWide=790:gboxMaxHigh=435
menu #1, "&File", "&Open", [doOpen], "&Save as BMP", [doSave], "E&xit", [quit]
graphicbox #1.g, 0, 0, gboxMaxWide, gboxMaxHigh
open "GDIPlus Image Loading - And More" for window_nf as #1
#1.g "down; fill 255 240 200; flush mainSegment"
#1 "trapclose [quit]"
wait
[doOpen]
filedialog "Open Image File","*.jpg;*.png;*.tiff;*.ico;*.bmp;*.gif",imgfile$
if imgfile$="" then
notice "No image file chosen."
wait
else
if hBitmap<>0 then 'if an image has been loaded, delete it first
unloadbmp "image"
'Remove from memory
calldll #gdi32,"DeleteObject",hBitmap as ulong, ret as ulong
'turn off scrollbars
#1.g "vertscrollbar off;horizscrollbar off"
end if
hBitmap=GDIPlusLoadImage(imgfile$)
if hBitmap<>0 then
bmpWide=BitmapWidth(hBitmap)
bmpHigh=BitmapHeight(hBitmap)
if bmpWide>gboxMaxWide then
'if width of bmp greater than maximum width of gbox, add scrollbar
gboxWide=gboxMaxWide
#1.g "horizscrollbar on 0 ";bmpWide
else
'set gbox width=image width
gboxWide=bmpWide
#1.g "horizscrollbar off"
end if
if bmpHigh>gboxMaxHigh then
'if height of bmp is greater than maximum height of gbox, add scrollbar
gboxHigh=gboxMaxHigh
#1.g "vertscrollbar on 0 ";bmpHigh
else
'set gbox height=image height
gboxHigh=bmpHigh
#1.g "vertscrollbar off"
end if
'resize gbox to fit image
#1.g "locate 0 0 ";gboxWide;" ";gboxHigh
#1 "refresh"
loadbmp "image",hBitmap
#1.g "delsegment mainSegment; discard" 'remove graphics from memory
#1.g "fill 255 240 200"
#1.g "drawbmp image 0 0;flush mainSegment"
else
notice "Unable to load image file!"
end if
end if
wait
[doSave]
if hBitmap<>0 then
filedialog "Save As BMP", "*.bmp", savefile$
if savefile$<>"" then
'assure that filename ends in .bmp extension
if lower$(right$(savefile$,4))<> ".bmp" then savefile$=savefile$+".bmp"
bmpsave "image", savefile$
end if
end if
wait
[quit]
if hBitmap<>0 then 'if an image has been loaded, delete it
unloadbmp "image"
'Remove from memory
calldll #gdi32,"DeleteObject",hBitmap as ulong, ret as ulong
end if
close #1 : end
function GDIPlusLoadImage(file$)
open "gdiplus.dll" for dll as #gdiplus
'this struct will be filled by API functions
STRUCT GDITOKEN, token as ulong
'we MUST fill this struct with GdiPlusVersion number
STRUCT GdiplusStartupInput,_
GdiplusVersion as ulong,_
DebugEventCallback as ulong,_
SuppressBackgroundThread as long,_
SuppressExternalCodecs as long
GdiplusStartupInput.GdiplusVersion.struct=1 'must be = 1
calldll #gdiplus,"GdiplusStartup",_
GDITOKEN as struct,_
GdiplusStartupInput as struct,_
status as ulong 'returns zero if successful
token=GDITOKEN.token.struct
if status<>0 then
GDIPlusLoadImage=0
else
wFile$=MultiByteToWideChar$(file$)
calldll #gdiplus,"GdipCreateBitmapFromFile", _
wFile$ as ptr,_ 'filename string in unicode (wide) character format
GDITOKEN as struct,_
status as ulong 'returns zero if successful
hBmpGdip=GDITOKEN.token.struct 'GDI+ bitmap returned in struct
if status<>0 then
GDIPlusLoadImage=0
else
'create GDI bitmap handle from GDI+ bitmap
calldll #gdiplus,"GdipCreateHBITMAPFromBitmap", _
hBmpGdip as ulong,_ 'GDIPlus bitmap
GDITOKEN as struct,_ 'bitmap handle will be returned in this struct
0 as ulong,_
status as ulong 'returns zero if successful
if status<>0 then
GDIPlusLoadImage=0
else
'get a bitmap handle we can use with Liberty BASIC's LOADBMP
GDIPlusLoadImage=GDITOKEN.token.struct
end if
calldll #gdiplus,"GdipDisposeImage",_ 'remove GDI+ bitmap
hImage as ulong,_ 'GDI+ bitmap handle
result as ulong
end if
calldll #gdiplus,"GdiplusShutdown",_ 'you must call this when finished
token as ulong,_ 'Token returned by a previous call to GdiplusStartup.
result as void 'no return from this function
close #gdiplus
end if
end function
function MultiByteToWideChar$(String$)
'converts any string into unicode
CodePage = 0 : dwFlags = 0 : cchMultiByte = -1
lpMultiByteStr$ = String$ : cchWideChar = len(String$) * 3
lpWideCharStr$ = space$(cchWideChar)
calldll #kernel32, "MultiByteToWideChar", _
CodePage as ulong, _ 'CP_ACP=0, ansi code page
dwFlags as ulong, _ 'use 0, flags for character translation
lpMultiByteStr$ as ptr,_'the ascii string to convert
cchMultiByte as long, _ 'len of string, -1 for null-terminated string
lpWideCharStr$ as ptr, _'buffer for returned ansi string
cchWideChar as long, _ 'size in wide characters of string buffer
result as long 'returns number of wide characters written to buffer
if result = 0 then
MultiByteToWideChar$ = ""
else
MultiByteToWideChar$ = left$(lpWideCharStr$, result * 2)
end if
end function
Function BitmapWidth(hBmp)
struct BITMAP,bmType as long,bmWidth As long,bmHeight As long,_
bmWidthBytes As long,bmPlanes as word,bmBitsPixel as word,bmBits as Long
length=len(BITMAP.struct)
calldll #gdi32, "GetObjectA", hBmp as ulong,_
length as long,BITMAP as struct,results as long
BitmapWidth=BITMAP.bmWidth.struct
End Function
Function BitmapHeight(hBmp)
struct BITMAP,bmType as long,bmWidth As long,bmHeight As long,_
bmWidthBytes As long,bmPlanes as word,bmBitsPixel as word,bmBits as Long
length=len(BITMAP.struct)
calldll #gdi32, "GetObjectA", hBmp as ulong,_
length as long,BITMAP as struct,results as long
BitmapHeight=BITMAP.bmHeight.struct
End Function