Inspired by this thread (http://www.masm32.com/board/index.php?topic=9528.0), I wrote an example of converting a BMP in memory to a JPG file. The GeneSys installation provides gdiplus.inc and gdiplus.lib
Other conversion options :
Quoteimage/gif
image/tiff
image/png
include GDIpBmpToJPG.inc
include gdiplus.inc
EXTERN pImage:BYTE
UnicodeStr PROTO :DWORD,:DWORD
GetEncoderClsid PROTO :DWORD,:DWORD
.data
szFileName db 'test.bmp',0
jpegFile db 'test.jpg',0
ImgType db 'image/jpeg',0
message db 'BMP file converted to JPG',0
caption db 'GDI+ demo',0
.data?
StartupInfo GdiplusStartupInput <?>
buffer db 32 dup(?)
pImageCodecInfo dd ?
token dd ?
BmpImage dd ?
.code
start:
mov eax,OFFSET StartupInfo
mov GdiplusStartupInput.GdiplusVersion[eax],1
invoke GdiplusStartup,ADDR token,ADDR StartupInfo,0
invoke UnicodeStr,ADDR szFileName,ADDR buffer
; convert szFileName to UNICODE
mov eax,OFFSET pImage
mov ecx,BITMAPFILEHEADER.bfOffBits[eax]
lea edx,[eax+ecx] ; points the array of bytes that contains the pixel data
add eax,SIZEOF BITMAPFILEHEADER ; points the BITMAPINFO structure
invoke GdipCreateBitmapFromGdiDib,eax,edx,ADDR BmpImage
; creates a Bitmap object based on a BITMAPINFO structure and
; an array of pixel data
invoke UnicodeStr,ADDR jpegFile,ADDR buffer
invoke GetEncoderClsid,ADDR ImgType,ADDR pImageCodecInfo
; get the class identifier (CLSID) of the encoder
; The encoder can be bmp,jpeg,gif,tiff or png
invoke GdipSaveImageToFile,BmpImage,ADDR buffer,eax,0
; save the image file
invoke VirtualFree,pImageCodecInfo,0,MEM_RELEASE
invoke GdipDisposeImage,BmpImage ; release the image
invoke GdiplusShutdown,token ; shutdown the GDI+ system
invoke MessageBox,0,ADDR message,ADDR caption,MB_OK
invoke ExitProcess,0
GetEncoderClsid PROC USES ebx edi sMimeType:DWORD,pMem:DWORD
LOCAL numEncoders:DWORD
LOCAL nSize:DWORD
LOCAL _buffer[32]:BYTE
invoke GdipGetImageEncodersSize,ADDR numEncoders,ADDR nSize
invoke VirtualAlloc,0,nSize,MEM_COMMIT,PAGE_READWRITE
mov edi,eax
mov eax,pMem ; = pImageCodecInfo
mov DWORD PTR [eax],edi
invoke GdipGetImageEncoders,numEncoders,nSize,edi
invoke UnicodeStr,sMimeType,ADDR _buffer
mov ebx,numEncoders
@@:
invoke StrCmpW,ADDR _buffer,ImageCodecInfo.MimeType[edi]
test eax,eax
jnz @f
sub ebx,1
add edi,SIZEOF ImageCodecInfo
jmp @b
@@:
lea eax,[edi+ImageCodecInfo.Clsid]
ret
GetEncoderClsid ENDP
UnicodeStr PROC USES esi src:DWORD,dest:DWORD
mov esi,src
mov edx,dest
xor eax,eax
sub eax,1
@@:
add eax,1
movzx ecx,BYTE PTR [esi+eax]
mov WORD PTR [edx+eax*2],cx
test ecx,ecx
jnz @b
ret
UnicodeStr ENDP
END start
[attachment deleted by admin]
Vortex,
EXTERN pImage:BYTE ?
Anyway, I am going to play with the Capture example. I always disliked the bitmap thing. The problem with me, though, is that when it comes to working with graphics I am pretty dense, maybe stupid. ::)
-- Paul
Hi Paul,
The BMP image is converted to a MS COFF object module to be linked with the project module :
bin2coff image.bmp image.obj _pImage
The image is now encapsulated in the object module as a binary data block :
Microsoft (R) COFF Binary File Dumper Version 5.12.8078
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.
\GeneSys\bin\dumpbin /HEADERS image.obj
Dump of file image.obj
File Type: COFF OBJECT
FILE HEADER VALUES
14C machine (i386)
1 number of sections
0 time date stamp Thu Jan 01 02:00:00 1970
323D6 file pointer to symbol table
1 number of symbols
0 size of optional header
184 characteristics
Line numbers stripped
Bytes reversed
32 bit word machine
SECTION HEADER #1
.data name
0 physical address
0 virtual address
3239A size of raw data
3C file pointer to raw data
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
C0300040 flags
Initialized Data
4 byte align
Read Write
The label pImage is the reference to the data block containing the BMP image bytes.
This new version has the capacity to set the compression level of JPG images.
To set the compression level, modify the value of ImgQuality :
ImgQuality dd 50 ; compression = 50 %
[attachment deleted by admin]
This new example loads a bitmap image with GdipCreateBitmapFromFile and saves the JPEG to a stream created by CreateStreamOnHGlobal. The JPEG in memory can be edited \ modifed before saving to disc. GetHGlobalFromStream and GlobalLock are used to determine the address of the JPEG image. The method IStream::Seek is called to find the size of the image. The JPEG is saved before terminating the application.
[attachment deleted by admin]
Vortex,
Okay, so now I will try to make good use of your hard work by applying it to the Capture utility. I always wanted to extend its capabilities, anyway, so now it might be a good time to do so now that the file sizes will be more manageable.
-- Paul
Hi Paul,
Once you get hBitmap the handle to the desktop, I guess you can use the GdipCreateBitmapFromHBITMAP function to create a bitmap object.