News:

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

Converting BMP to JPG

Started by Vortex, July 27, 2008, 08:19:32 PM

Previous topic - Next topic

Vortex

Inspired by this thread, 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]

PBrennick

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
The GeneSys Project is available from:
The Repository or My crappy website

Vortex

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.

Vortex

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]

Vortex

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]

PBrennick

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
The GeneSys Project is available from:
The Repository or My crappy website

Vortex

Hi Paul,

Once you get hBitmap the handle to the desktop, I guess you can use the GdipCreateBitmapFromHBITMAP function to create a bitmap object.