News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Loading images as a bitmap

Started by Jimg, April 03, 2009, 07:31:36 PM

Previous topic - Next topic

Jimg

Here's some code to play with.  It will load and image either from a file or from a resource embedded in the exe.

to use:

inv GetMyBitmap,133,0,addr hbmp,addr tloc     ; when getting a resource by id
  or
invoke GetMyBitmap,0,addr filename,addr hbmp,addr tloc  ; when getting a file

.if hbmp==0
    invoke MessageBox,0,tloc,0,0
    jmp errorroutine
.endif


here, tloc is the address of a dword that will receive the address of an error buffer if there is an error.

edit:  fixed error. new code in my next post.

Rainstorm


Jimg

#2
Sorry about that.  Soon as I moved it to another program, I found a problem.  Here's the new code.

Edit:  and again I left out a declaration.  This is now complete.

ifndef GDIPLUS_INC
    include \masm32\include\gdiplus.inc
    includelib \masm32\lib\gdiplus.lib
endif
   
.data
ALIGN 4
GdiplusStartupInput struc
    GdiplusVersion           dd ?
    DebugEventProc           dd ?
    SuppressBackgroundThread BOOL ?
    SuppressExternalCodecs   BOOL ?
GdiplusStartupInput ends

GdipSi GdiplusStartupInput <1,0,0,0>
.data?
token   dd ?  ; pointer to gdi+ thingy like a handle.  Save for shutdown.
   
gmbErrBuff db 256 dup (?)
.code
gmbDoErrCmt proc
    invoke GetLastError
    mov edx,eax
    invoke FormatMessage,FORMAT_MESSAGE_FROM_SYSTEM,0,edx,0,addr gmbErrBuff,256,0
    ret
gmbDoErrCmt endp

gmberrtst macro testfor,gmbinst:vararg
    invoke gmbinst  ; execute the command
    ifidni <testfor>,<nz>
        .if eax
    elseifidni <testfor>,<z>
        .if eax==0
    else
        .if eax==testfor
    endif
            call gmbDoErrCmt
            jmp gmbErrRet
        .endif
endm
               
; Load an image into a bitmap and return it's handle    - by Jim Giordano
; Valid image types are bmp, png, tif, gif, and jpg.
; This routine will return the handle to a bitmap
; If ResourceID is zero then
;   FileName is a pointer to the full path and file name to load
; If ResourceID is non-zero, FileName is ignored and
;   ResourceID is the id of a resource of RT_RCDATA type
;   e.g.  a line in a resource file like  130 RCDATA DISCARDABLE "mygrid.png"

; If the image is found, BitmapHandleOut will contain it's handle
; if an error occurs, BitmapHandleOut will contain zero, and gmbErrorCmt will point to an error string

; Requires gdiplus lib

; Free for all purposes


GetMyBitmap proc ResourceID:dword,FileName:dword,BitmapHandleOut:dword,gmbErrorCmt:dword
    local gmbhInst:dword,gmbfname:dword,gmbErrFlag:dword,gmbTmpPath[256]:byte
    local gmbPrefix:dword,gmbFileName[256]:byte,gmbRes:dword,gmbLoc,gmbSize,gmbHan
    local gmbUnicodeName[512]:byte,gmbbo:dword,gmbbmp
    pusha   ; uses just about everything
    mov gmbErrFlag,0   ; install temporary per-thread error handler
    mov gmbHan,0
    mov esi,gmbErrorCmt
    mov [esi],offset gmbErrBuff ; where error comment will be if any
    assume fs:nothing  ;MASM assumes the use of this register to be ERROR by default
    push offset gmbExceptionHandler
    push fs:[0]
    mov fs:[0],esp
   
    mov esi,BitmapHandleOut   ; assume error
    mov dword ptr [esi],0
    push FileName
    pop gmbfname   
   
    .if ResourceID
        inv GetModuleHandle,0
        mov gmbhInst,eax
        gmberrtst z, FindResource,gmbhInst,ResourceID,RT_RCDATA
        mov gmbRes,eax
        gmberrtst z, LoadResource,gmbhInst,eax
        gmberrtst z, LockResource,eax
        mov gmbLoc,eax
        gmberrtst z, SizeofResource,hInst,gmbRes
        mov gmbSize,eax
        gmberrtst z, GetTempPath,256,addr gmbTmpPath
        mov gmbPrefix,00626D67h  ; "gmb"
        lea eax,gmbFileName
        mov gmbfname,eax    ; save address
        gmberrtst z, GetTempFileName,addr gmbTmpPath,addr gmbPrefix,0,gmbfname
        gmberrtst -1, CreateFile,gmbfname,GENERIC_WRITE,0,0,CREATE_ALWAYS,FILE_ATTRIBUTE_TEMPORARY,0   
        mov gmbHan,eax
        gmberrtst -1, _lwrite,gmbHan,gmbLoc,gmbSize
        gmberrtst -1, _lclose,gmbHan
    .endif
    gmberrtst z, MultiByteToWideChar,CP_ACP,0,gmbfname,-1,addr gmbUnicodeName,256  ; need full path unicode names
    gmberrtst nz, GdiplusStartup,addr token,addr GdipSi,0 ; get gdi+ working
    ;invoke MessageBoxW,0,addr gmbUnicodeName,0,0
    gmberrtst nz, GdipCreateBitmapFromFile,addr gmbUnicodeName,addr gmbbo ; get the image into a "bitmap object"
    gmberrtst nz, GdipCreateHBITMAPFromBitmap,gmbbo,addr gmbbmp,0        ; convert to a normal gdi bitmap
    gmberrtst nz, GdipDisposeImage,gmbbo                               ; return "bitmap object"
    gmberrtst nz, GdiplusShutdown,addr token                          ; all done with gdi+
    mov eax,BitmapHandleOut
    push gmbbmp
    pop [eax]
   
    gmbErrRet:
    pop fs:[0]   ; Uninstall per-thread error handler
    add esp,4
    .if gmbErrFlag
        lea esi,gmbErrorCmt
        call gmbDoErrCmt
        mov BitmapHandleOut,0
    .endif
    .if gmbHan
        invoke DeleteFile,gmbfname
    .endif
    popa
    ret

gmbExceptionHandler: ; PROC pExcept, pFrame, pContext, pDispatch
    mov eax,[esp+12]  ; pContext
    mov [eax].CONTEXT.regEip,offset gmbErrRet
    mov eax,ExceptionContinueExecution
    mov gmbErrFlag,1
    ret

GetMyBitmap endp


Jimg

Here's a little test app.  It will display either one of the five images stored in the resource, or you may select any file of the five valid type by clicking on the file menu item.

[attachment deleted by admin]