News:

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

OleLoadPicturePath

Started by Jimg, February 11, 2009, 07:28:37 PM

Previous topic - Next topic

Jimg

I trying to figure out how to use OleLoadPicturePath to load a jpg from a file.  Does anyone know the value riid is supposed to have?  I've found references to IID_IPicture but I can't find the value of that either.
Or Anyone want to share uncopyrighted code (i.e. not Murphy) for using this api?  Normally I struggle through some unintelligible example from microsoft, but I can't find a single example from them of using this api.

Vortex

Hi Jimg,

Here is where I found a reference to OleLoadPicturePath :

OleLoadPicturePath(L"foo.jpg", 0, 0, 0, IID_IPicture, (void**)&pIPicture);

Rendering GIF, JPEG, Icon, or Bitmap Files with OleLoadPicture

The difficulty  is to convert the pIPicture pointer to hBitmap. Here is a trial :


    .IF uMsg==WM_INITDIALOG

        invoke  GetCurrentDirectory,300,ADDR buffer
        invoke  lstrcat,ADDR buffer,ADDR filename
        invoke  UnicodeStr,ADDR buffer,ADDR UnicodeName
        invoke  OleLoadPicturePath,ADDR UnicodeName,0,0,0,ADDR IID_IPicture,ADDR pPicture
        invoke  BitmapFromPicture,pPicture
        mov     hBitmap,eax

        mov     eax,pPicture
        push    eax
        mov     eax,DWORD PTR [eax]
        call    IPicture.Release[eax]


As a quick solution, I used Murphy's BitmapFromPicture routine to solve the problem but you can write your own function to do the pointer to hBitmap convertion.

IID_IPicture is a GUID defined like the following :

IID_IPicture  GUID <7BF80980h,0BF32h,101Ah,<8Bh,0BBh,00h,0AAh,00h,30h,0Ch,0ABh>>
[attachment deleted by admin]

Jimg

Thanks Vortex, I'll look over what you gave me :U

Vortex

Hi Jimg,

I found another article :

Going from a JPG/GIF/BMP File to a HBITMAP File Using Plain API

Following the method described in the article, here is how to convert pPicture to hBitmap :


.IF uMsg==WM_INITDIALOG

        invoke  GetCurrentDirectory,300,ADDR buffer
        invoke  lstrcat,ADDR buffer,ADDR filename
        invoke  UnicodeStr,ADDR buffer,ADDR UnicodeName
        invoke  OleLoadPicturePath,ADDR UnicodeName,0,0,0,ADDR IID_IPicture,ADDR pPicture

        lea     eax,[hTempBmp]
        push    eax
        mov     eax,pPicture
        push    eax
        mov     eax,DWORD PTR [eax]
        call    IPicture.get_Handle[eax]

        invoke  CopyImage,hTempBmp,IMAGE_BITMAP,0,0,LR_COPYRETURNORG
        mov     hBitmap,eax

        mov     eax,pPicture
        push    eax
        mov     eax,DWORD PTR [eax]
        call    IPicture.Release[eax]

[attachment deleted by admin]

Jimg

Thanks again Erol, works great.  It took me half an hour before I realized I really needed the full path, unlike LoadImage which worked fine from just the file name without the path.

Jimg

This has been working really great Erol, thanks!

I would now like to be able to read a .tif file and load into the bitmap of a dc.  No luck so far.  Is there any standard api calls that will load a .tif file?  Searching MSDN, there was many ariticles on tif's, but I couldn't find any actual code.  Searching google, there are tons of converters available, but again, I couldn't find any example code.

Vortex

Hi Jimg,

You are welcome. Many thanks for your tests.

Here is what I found :

LibTIFF - TIFF Library and Utilities

Working with TIFF Images

Jimg

After screwing around for weeks, I finally gave up and went to gdiplus.  It seems to be able to load any image type with the same code, so I'm happy.  I'm sure there's more efficient ways to do this, but it works for me.  (Suggestions are always welcome.)

Thanks to many people who's code I shamelessly stole from many different places to get this to work.

The purpose of this code is to load any type image into a dib I can efficiently accesses on the pixel level-
.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.
btmap   BITMAP <>
bwidth  equ btmap.bmWidth   ; width of images
bheight equ btmap.bmHeight  ; height of images
bitsptr dd ?
.data
bih   BITMAPINFOHEADER <sizeof BITMAPINFOHEADER,0,0,1,32,BI_RGB,0,0,0,0,0>
.code
WndProc Proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
    local hdc,ps:PAINTSTRUCT,tdc,tbmp
    .if uMsg==WM_CREATE

        inv GdiplusStartup,addr token,addr GdipSi,0 ; get gdi+ working
        inv MultiByteToWideChar,CP_ACP,0,addr filename,-1,addr UnicodeName,256  ; need full path unicode names
        inv GdipCreateBitmapFromFile,addr UnicodeName,addr obmp ; get the image into a "bitmap object"
        inv GdipCreateHBITMAPFromBitmap,obmp,addr hbmp,0        ; convert to a normal gdi bitmap
        inv GdipDisposeImage,obmp                               ; return "bitmap object"
        inv GdiplusShutdown,addr token                          ; all done with gdi+

        inv GetObject,hbmp,sizeof btmap,addr btmap
        inv GetDC,hWnd      ; get dc of window
        mov hdc,eax
        inv CreateCompatibleDC,hdc
        mov tdc,eax         ; temp dc for bitmap manipulation
        inv SelectObject,tdc,hbmp   ; load it in so we can do something with it
        m2m bih.BITMAPINFOHEADER.biWidth,bwidth  ; set width and height in bitmapinfoheader
        mov eax,bheight     ; so we can make a dib
        neg eax             ; dibs are backward
        mov bih.BITMAPINFOHEADER.biHeight,eax
        inv CreateDIBSection,hdc,addr bih,DIB_RGB_COLORS,addr bitsptr,0,0
        mov hdib,eax    ; something we can reference directly
        inv GetDIBits,tdc,hbmp,0,bheight,bitsptr,addr bih,DIB_RGB_COLORS ; now copy bitmap to dib   
        inv CreateCompatibleDC,hdc  ; setup a hidden memory dc buffer for updating the screen
        mov mdc,eax
        inv SelectObject,mdc,hdib   ; associate with the dib
        inv DeleteObject,hbmp
        inv DeleteDC,tdc
        inv ReleaseDC,hWnd,hdc

    .elseif uMsg==WM_PAINT
       
        inv BeginPaint,hWnd,addr ps
        mov hdc,eax
        inv BitBlt,hdc,0,0,bwidth,bheight,mdc,0,0,SRCCOPY
        inv EndPaint,hWnd,addr ps


I'm sure one of you gdi+ gurus know an api to do this in a lot fewer steps, so speak up!

Vortex

Hi Jimg,

Nice work. Before terminating the application, do you restore the original handle values of SelectObject?

Jimg

It depends on how I feel that day :wink

I read somewhere that replacing the 1x1 bit bitmap is a waste of time.  I've never had any problems, but it's probably good form.

Rainstorm

Vortex, some good links there.. thanks