Image Loading with GDI Plus

Simple Demo
Extended Demo


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


SIMPLE DEMO

'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


EXTENDED DEMO


'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


Home

Source Code

Utilities

Internet

Games

Graphics

Media Demos

Snippets

DLL's

API Resources

Freeware

LB 4 Companion

Mastering LB 3

LB Workshop

Game Workshop

Links

Index