After reading the first 50 or so pages of the libpng manual I gave up. I simply need to convert a png image to a bitmap image, I am not interested in learning to use libpng which comes with the most rambling, long winded documentation I have ever had the misfortune to encounter. Does anyone know of a library or routine that will convert a png image in memory to a bitmap ?
this may help Donkey:
http://www.madwizard.org/programming/projects/pnglib
I think GDI+ might be able to do that, depending on what you mean by a png image in memory.
Google for png2bmp.
Hi Rags,
I should have checked Thomas' site, thanks.
Hi Michael,
I will have a look at the GDI+ flat API, the PNG is embedded in a file, I have to extract it to a buffer then display it.
Hi Doc,
Thanks, I will look at the C source code. Problem is that GoAsm, though it supports libs does not support lib chains where one library calls a function in another library. I can usually find a way around it but it's a chore that I hoped to avoid.
Hi donkey,
The attached example converts a PNG in memory to bitmap with GDI+
The steps of the process :
- The PNG in memory is written to a stream
- The image in the stream is read by GDI+ and saved to another stream as BMP.
- The stream is written to disc.
A similar example is available from here (http://www.masm32.com/board/index.php?topic=9577.0)
[attachment deleted by admin]
Hi Vortex,
Thanks, I already have my solution, simple and direct...
PNG2HBMP FRAME pMemory,dwSize
LOCAL pStream :D
LOCAL pGlobal :D
LOCAL pBitmap :D
LOCAL hBitmap :D
mov D[pStream],NULL
invoke CoTaskMemAlloc, [dwSize]
mov [pGlobal],eax
invoke MemCopy,[pMemory],[pGlobal],[dwSize]
invoke CreateStreamOnHGlobal, [pGlobal], TRUE, ADDR pStream
test eax,eax
jz >
; no interface
invoke GlobalFree,[pGlobal]
xor eax,eax
ret
:
invoke gdiplus.dll:GdipCreateBitmapFromStream,[pStream],offset pBitmap
invoke gdiplus.dll:GdipCreateHBITMAPFromBitmap,[pBitmap],offset hBitmap,0FFFFFFFFh
CoInvoke(pStream,IPicture.IUnknown.Release)
invoke GlobalFree,[pGlobal]
mov eax,[hBitmap]
RET
ENDF
Just have to do a bitof research on how to release the gdiplus bitmap object, I assume its GdipDisposeImage
Actually it works amazingly well, I had conversion routines for a bunch of different image types that can all be replaced by the one call now. I have yet to find one that it doesn't load and convert to a bitmap handle. BTW, I think
invoke gdiplus.dll:GdipDisposeImage,[pBitmap]
Releases the bitmap object.
Hi donkey,
Nice work.
invoke GlobalFree,[pGlobal]
This is a double free here. No need for this line.
From MSDN :
Quote
fDeleteOnRelease [in]
A value that indicates whether the underlying handle for this stream object should be automatically freed when the stream object is released. If set to FALSE, the caller must free the hGlobal after the final release. If set to TRUE, the final release will automatically free the hGlobal parameter.
invoke CreateStreamOnHGlobal, [pGlobal],
TRUE, ADDR pStream
http://msdn.microsoft.com/en-us/library/aa378980(VS.85).aspx
Hi Vortex,
Thanks, just a reflex action freeing memory. GlobalSize shows 0 after the release so you're right it is freed and I have removed the call. A quick check shows GDI+ is redistributable down to Win98 so compatibility is there although I only really write code to Win2K+ anymore it's nice to know.
ConvertImage FRAME pMemory,dwSize
LOCAL pStream :D
LOCAL pGlobal :D
LOCAL pBitmap :D
LOCAL hBitmap :D
mov D[pStream],NULL
invoke CoTaskMemAlloc, [dwSize]
mov [pGlobal],eax
invoke MemCopy,[pMemory],[pGlobal],[dwSize]
invoke CreateStreamOnHGlobal, [pGlobal], TRUE, ADDR pStream
test eax,eax
jz >
; no interface
invoke CoTaskMemFree,[pGlobal]
xor eax,eax
ret
:
invoke GdipCreateBitmapFromStream,[pStream],offset pBitmap
invoke GdipCreateHBITMAPFromBitmap,[pBitmap],offset hBitmap,0FFFFFFFFh
invoke GdipDisposeImage,[pBitmap]
CoInvoke(pStream,IStream.IUnknown.Release)
mov eax,[hBitmap]
RET
ENDF
Hi donkey,
Another test : I created the stream without copying the data block. Setting the size of stream worked for me.
invoke CreateStreamOnHGlobal,ADDR pPNG,TRUE,ADDR pPNGstream ; pPNG is equal to pMemory in the GoAsm code
mov eax,pPNGstream
push 0
push PNG_FILE_SIZE ; equal to dwSize in the GoAsm code
push eax
mov eax,DWORD PTR [eax]
call IStream.SetSize[eax]
If you have the time, could you try this method in your procedure? I would like to know if this approach is correct.
In your code :
invoke CreateStreamOnHGlobal, [pGlobal], TRUE, ADDR pStream
To test the method, you need to replace pGlobal with pMemory and set the size of the stream with SetSize.
Thanks.
Hi Vortex,
That will fail in my case, pMemory points to a location in a memory mapped file and that is not a Global memory object so it is not compatible with CreateStreamOnHGlobal. It is more general purpose to simply make sure that the memory object matches the specifications for the API.
edit:
A quick check (because I was curious) shows that yes it does fail with virtual memory objects (like mapped files), SetSize has no effect since no interface was returned.
Curious, are the graphics in question well-suited to PNG? i.e., low-color lineart or raster/pixel art? Since PNG is a lossless compression, dithering and/or reducing the color count (of high-color images such as photos and renders) prior to saving as .png usually results in a drastically reduced filesize, with little visible artifacting.
Quote from: Mark Jones on January 05, 2009, 03:34:32 AM
Curious, are the graphics in question well-suited to PNG? i.e., low-color lineart or raster/pixel art? Since PNG is a lossless compression, dithering and/or reducing the color count (of high-color images such as photos and renders) prior to saving as .png usually results in a drastically reduced filesize, with little visible artifacting.
Not my graphics, you can find what I needed them for here...
http://www.masm32.com/board/index.php?topic=10610.0
Just some fun with MP3 files, most of what I buy from Apple iTunes has PNG attachments so they represent the bulk of my MP3 collection.
Hi donkey,
Thanks for the test and info. Yes, a convertion routine should take in account virtual memory objects.