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.
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 (http://www.codeproject.com/KB/graphics/render.aspx?display=PrintAll&fid=1289&df=90&mpp=25&noise=3&sort=Position&view=Quick&fr=26&select=96430)
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]
Thanks Vortex, I'll look over what you gave me :U
Hi Jimg,
I found another article :
Going from a JPG/GIF/BMP File to a HBITMAP File Using Plain API (http://www.codeguru.com/cpp/g-m/bitmap/article.php/c4935)
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]
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.
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.
Hi Jimg,
You are welcome. Many thanks for your tests.
Here is what I found :
LibTIFF - TIFF Library and Utilities (http://www.libtiff.org)
Working with TIFF Images (http://www.codeguru.com/cpp/g-m/bitmap/otherformats/article.php/c4933)
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!
Hi Jimg,
Nice work. Before terminating the application, do you restore the original handle values of SelectObject?
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.
Vortex, some good links there.. thanks