Older Version
Newer Version
JanetTerra
Dec 21, 2009
==Getting Image File Information with GDI32== While it is possible to [[GraphicDimensions|open and read any image file as a sequential file to find the image width and height]], it may be easier to use the GDI32 {{GetObjectA}}. {{GetObjectA}} retrieves information for all bitmaps in memory. [[GDIPlusLoadAnyImage|Load the image first with GDIPlus]] with a call to {{GdipCreateBitmapFromFile}}. Once the image is loaded, call {{GetObjectA}} to retrieve information. This code is based in part upon Alyce Watson's demo [[http://babek.info/libertybasicfiles/lbnews/nl108/sprite.htm|Sprite in a Box]] in the [[newsletter.2003#toc4|Liberty BASIC Newsletter, Issue #108]]. The code also uses Dan Teel's demo [[GDIPlusLoadAnyImage|Load Any Image with GDIPlus]]. Two structs are needed. The first is for the {{GetObjectA}} code. The struct holds the bitmap information. [[code]] Struct ImageInfo, _ imgType as Long, _ imgWidth as Long, _ imgHeight as Long, _ imgWidthBytes as Long, _ imgPlanes as Word, _ imgBitsPixel as Word, _ imgBits as Long [[code]] The second struct is for the {{GdipCreateBitmapFromFile}} code. [[code]] Struct doubleWord, a as uLong [[code]] Once the image is loaded and {{GetObjectA}} is called, the ImageInfo struct will contain the bitmap. Copy the width and height information from the struct to numeric variables. [[code]] imgWidth = ImageInfo.imgWidth.struct imgHeight = ImageInfo.imgHeight.struct [[code]] The advantages to loading an image with {{GdipCreateBitmapFromFile}} and then calling {{GetObjectA}} to find the width and height of the image are >> 1. No parsing of the image extension is needed to identify the image format >> 2. No complicated math formulas are needed to extract the width and height of the format >> 3. No error is given when trying to access a file path longer than 128 characters When the image is no longer needed, delete the image from memory with {{DeleteObject}}. [[code]] Call DeleteObject hImage Sub DeleteObject hImage CallDLL #gdi32, "DeleteObject", _ hImage as uLong, _ result as Long End Sub [[code]] ===Demo to Load an Image with GdipCreateBitmapFromFile and Find Dimensions with GetObjectA=== [[code format="vbnet"]] ' Extension variable for Filedialog ' Valid image formats are bmp, gif, ico, jpg, png, and tiff iExt$ = "*.bmp;*.gif;*.ico;*.jpg;*.png;*.tiff" ' Variables to hold the width and height of the image imageWidth = 0 imageHeight = 0 ' Struct necessary for loading an image with GDIPlus Struct doubleWord, a as uLong ' Struct necessary for returning image file information Struct ImageInfo, _ imgType as Long, _ imgWidth as Long, _ imgHeight as Long, _ imgWidthBytes as Long, _ imgPlanes as Word, _ imgBitsPixel as Word, _ imgBits as Long ' Design a GUI to host the image WindowWidth = 800 WindowHeight = 600 UpperLeftX = Int((DisplayWidth - WindowWidth) / 2) UpperLeftY = Int((DisplayHeight - WindowHeight) / 2) ' Design a graphicbox to display the image Stylebits #main.g, 0, _WS_BORDER, 0, 0 Graphicbox #main.g, 0, 0, 792, 580 Open "Getting the Image Width and Height with GetObjectA" for Window_nf as #main #main, "Trapclose [closeApp]" #main, "Font Verdana 10 Bold" hMain = hWnd(#main) hG = hWnd(#main.g) #main.g, "Down" ' Load an image file Filedialog "Image to Load", iExt$, imagePathFile$ ' Load the image using GDIPlus, hImage is the returned handle to the bitmap in memory hImage = LoadImgFromFile(imagePathFile$) ' Get the bitmap information using GetObjectA imageDimen$ = ImageDimensions$(hImage) imageW = Val(Word$(imageDimen$, 1, Chr$(0))) imageH = Val(Word$(imageDimen$, 2, Chr$(0))) ' Load the bitmap in memory Loadbmp "pic", hImage ' Draw the image using native LB command Drawbmp #main.g, "Drawbmp pic 10 10; Flush" ' Resize the graphicbox to the size of the image #main.g, "Locate 0 0 ";imageW + 20;" ";imageH + 20 #main, "Refresh" ' Give the width and height of the image msg$ = "Image Dimensions";Chr$(10);Chr$(13); _ "Width: ";imageW;" pixels";Chr$(10);Chr$(13); _ "Height: ";imageH;" pixels";Chr$(10);Chr$(13) Notice msg$ Wait [closeApp] ' Unload the native LB bitmap Unloadbmp "pic" ' Release memory from GDIPlus loaded image Call DeleteObject hImage Close #main End Function ImageDimensions$(hImage) lStruct = Len(ImageInfo.struct) CallDLL #gdi32, "GetObjectA", _ hImage as uLong, _ lStruct as Long, _ ImageInfo as struct, _ result as Long imgWidth = ImageInfo.imgWidth.struct imgHeight = ImageInfo.imgHeight.struct ImageDimensions$ = Str$(imgWidth);Chr$(0);Str$(imgHeight) End Function Function wChar$(string$) For i = 1 to Len(string$) wChar$ = wChar$ + Mid$(string$, i, 1) + chr$(0) Next i wChar$ = wChar$ + Chr$(0) + Chr$(0) End Function Function LoadImgFromFile(picFile$) Open "gdiplus.dll" for dll as #gdip gdistart$=Chr$(1) For i = 1 to 15 gdistart$ = gdistart$ + Chr$(0) Next i Calldll #gdip,"GdiplusStartup", _ doubleWord as struct, _ gdistart$ as Ptr, _ status as uLong token=doubleWord.a.struct If status <> 0 Then LoadImgFromFile = 0 Else wFileLoc$=wChar$(picFile$) Calldll #gdip,"GdipCreateBitmapFromFile", _ wFileLoc$ as Ptr, _ doubleWord as struct, _ status as uLong hPic = doubleWord.a.struct If status <>0 then LoadImgFromFile=0 Else CallDLL #gdip,"GdipCreateHBITMAPFromBitmap", _ hPic as uLong, _ doubleWord as struct, _ 0 as uLong, _ status as uLong hImage=doubleWord.a.struct If status <> 0 Then LoadImgFromFile = 0 Else LoadImgFromFile = hImage End if CallDLL #gdip,"GdipDisposeImage", _ hPic as uLong, _ result as uLong End If CallDLL #gdip,"GdiplusShutdown", _ token as uLong, _ result as uLong End If Close #gdip End Function Sub DeleteObject hImage CallDLL #gdi32, "DeleteObject", _ hImage as uLong, _ result as Long End Sub [[code]] ----