News:

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

Problem saving an image to file

Started by minor28, December 10, 2010, 10:48:34 AM

Previous topic - Next topic

minor28

I have an image loaded. I select a rectangle (left,top,w and h) of the image and save it to a file. This is working allright. Code like this:


invoke GdipCreateBitmapFromGdiDib,pBMI,pPixelData,addr srcBitmap
invoke GdipCloneBitmapAreaI,left,top,w,h,PixelFormat8bppIndexed,srcBitmap,addr ppBitmap
invoke GdipSaveImageToFile,ppBitmap,addr FileName,addr ici,addr eps


On the image I draw a line. Now I want to save the same part with the line. I do it like this:


invoke CreateCompatibleDC,hDC
mov hcdc,eax
;Create a new buffer
invoke CreateDIBSection,hDC,pBMI,DIB_RGB_COLORS,addr ppvBits,0,0
mov hdib,eax
invoke SelectObject,hcdc,hdib
mov hObj,eax
;Copy from hDC to new buffer
invoke BitBlt,hcdc,0,0,w,h,hDC,left,top,SRCCOPY
invoke GdiFlush

invoke GetObject,hdib,sizeof dibsect,addr dibsect
.if eax
lea eax,srcBitmap
push eax
lea eax,dibsect
add eax,DIBSECTION.dsBm
mov eax,dword ptr [eax].BITMAP.bmBits
push eax
lea eax,dibsect
add eax,DIBSECTION.dsBmih
push eax
call GdipCreateBitmapFromGdiDib

invoke GdipCloneBitmapAreaI,0,0,w,h,PixelFormat8bppIndexed,srcBitmap,addr ppBitmap
.endif
invoke GdipSaveImageToFile,ppBitmap,addr FileName,addr ici,addr eps


This will save a black image and not the original image with the line. I cannot figure out what I am doing wrong. I have debugged and all values seems to bee OK.

I would appreciate some help here.

Regards

minor28

OK, finally got. Apparently I would not use dibsect.


invoke CreateCompatibleDC,hDC
mov hcdc,eax
;Create a new buffer
invoke CreateDIBSection,hDC,pBMI,DIB_RGB_COLORS,addr ppvBits,0,0
mov hdib,eax
invoke SelectObject,hcdc,hdib
mov hObj,eax
;Copy from hDC to new buffer
invoke BitBlt,hcdc,0,0,w,h,hDC,left,top,SRCCOPY
invoke GdiFlush

invoke GdipCreateBitmapFromGdiDib,pBMI,ppvBits,addr srcBitmap
invoke GdipCloneBitmapAreaI,left,top,w,h,PixelFormat8bppIndexed,srcBitmap,addr ppBitmap
invoke GdipSaveImageToFile,ppBitmap,addr FileName,addr ici,addr eps

xandaz

   Are there any more examples on how to save a bitmap? Anyone? Do i need to CreateDIBSect and use FileMapping? I'm making this drawing thingy and i'm stuck on the save bitmap part. Help needed....

baltoro

XANDAZ,   
A DibSection is basically a bitmap loaded into memory as a continuous block of data. As I recall. one of the header structures is not necessary, and, so it is not included in the DibSection (BITMAPFILEHEADER Structure). When you save a bitmap, you save it to a file, which can be read and loaded by Paint, or Photoshop, or any photo editing program. You can actually correctly write a bitmap file using CreateFile and WriteFile, and a number of other GDI (or GDI+) functions. The bitmap file can then be compiled as a resource into your executable. It's basically pretty simple, as the bitmap is the native Windows image type. There are, however, several complications: color depth (the biBitCount field of the BITMAPINFOHEADER Structure), and the fact that there are over a dozen different byte formats,...and, the really old bitmap types can have palettes specified (these are typically bitmaps with only 256 possible colors). You can avoid all that by simply specifying a 24-bit color depth (which eliminates the possibility of having to include an array of color indexes or having to specify one of the older Bitmap Header Types)
Here is the MSDN overview of: Bitmaps
This MSDN page explains: Bitmap Storage
Here is a blog entry from Raymond Chen: The Format of Bitmap Resources
Baltoro

MichaelW

#4
In the imdialogs.zip attachment here:

http://www.masm32.com/board/index.php?topic=9637.0

In the file support.asm, there is a CreateBitmapFile procedure that takes a device-dependant bitmap in memory and stores it to a file.

BTW, I have since determined that you can modify the procedure to support 16-bpp output by simply adding the value 16 to the CASE statement on line 264:

    ;----------------------------------------------------------------
    ; Set the output bpp, or fail if the bpp is not 4, 8, 16, or 24.
    ;----------------------------------------------------------------

    mov eax, bppDib
    SWITCH eax
      CASE 4, 8, 16, 24
        mov [ebx].BITMAPINFO.bmiHeader.biBitCount, ax
      DEFAULT
        invoke HeapFree, hHeap, 0, ebx
        ret
    ENDSW

eschew obfuscation

xandaz

   i really haven't looked into baltoro's provided links. Do 4 and 8 bit dephs have the array of rgb quads as large as 16*Quad and 256*quad or are there only as much quads as colors in the bitmap? thanks guys. Bery useful information. Also i was checking the gimp's brushes and saw it has crosses and other types. This arent made throught Pen creation funtions are they? Im asking because i tried and it all comes out the same. Round like pen.
   Bests from X.

dedndave

no - 4-bit BMP's (16-colour) have 2 pixels per image data byte
8-bit BMP's (256-colour) have 1 pixel per image data byte
both of those formats have a palette that follows the header and preceeds the image data
each palette entry is a quad
24-bit and 32-bit BMP's have the quads, a header, and no palette (and can be rather large)

i believe all BMP formats begin each line on 4-byte boundries

in the "old standard" BMP file, the first line in the file is the last (bottom) line of the image
however, they now use a negative image height value and invert the line order

FORTRANS

Hi,

   In 24 and 32-bit BMPs, the pallet is optional.  That bit me
at one time as most (?) don't have it.  But at least some do.
And there are variations on how big, and the contents, of the
headers.

Cheers,

Steve N.

dedndave

well - the header accomodates almost anything you want - lol
you can even add remarks, if you like

but, i don't know how a palette would apply in an image that has all the colours defined in data
i suppose it could be a set of colours used to set up the video palette registers in systems that do not have true-colour