let's say i have painted something on a dc created with CreateCompatibleDC (later CreateCompatibleBitmap and SelectObject). how can i save the content as a bitmap?
and why does rc.exe say that the bitmap painted with "Paint" isn't a windows 3.0 bitmap or whatever?
bye
A bitmap file consists of a few structures and the image data. At the start of the file, there's an BITMAPFILEHEADER structure, followed by a BITMAPINFO structure. The BITMAPINFO is a BITMAPINFOHEADER structure (with size, color, etc) information, followed by the raw image data.
So all you have to do is fill in a BITMAPFILEHEADER and a BITMAPINFOHEADER structure, write both to a file and then write all the image data. GetDIBits can be a usefull function.
Thomas
ok, so i've to open a new file, write the BITMAPFILEHEADER structure and then the BITMAPINFOHEADER to it, and then the raw bitmap data. but how to write the raw bitmap data exactly? e.g.
invoke CreateCompatibleDC,NULL
mov hBackBuffer,eax
invoke GetDC,hWin
push eax
invoke CreateCompatibleBitmap,eax,157,150
mov hBackBitmap,eax
pop eax
invoke ReleaseDC,hWin,eax
invoke SelectObject,hBackBuffer,hBackBitmap
invoke Ellipse,hBackBuffer,5,5,50,50
how can i write the DC (hBackBuffer) to the file now? i don't understand that.
tnxI'll write some code for you today.
Thomas
Here's some code:
SaveDCToBitmap PROTO STDCALL :DWORD, :DWORD, :DWORD
SaveDCToBitmap proc uses ebx hDC:DWORD, hBitmap:DWORD, lpFileName:DWORD
LOCAL hFile:DWORD
LOCAL BytesWritten:DWORD
LOCAL hTempMem:DWORD, pTempMem:DWORD
LOCAL hImageMem:DWORD, pImageMem:DWORD
LOCAL HeaderAndPaletteSize:DWORD
LOCAL retval:DWORD
LOCAL bfh:BITMAPFILEHEADER
;--- Create new file (NOTE: CREATE_ALWAYS overwrites old file!!!!!) ---
invoke CreateFile, lpFileName, GENERIC_WRITE, 0, \
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL
.IF eax==INVALID_HANDLE_VALUE
xor eax, eax
ret
.ENDIF
mov hFile, eax
;--- The bitmap file header will be written at the end, so skip it now ---
invoke SetFilePointer, hFile, SIZEOF BITMAPFILEHEADER, 0, FILE_BEGIN
;--- allocate memory for bitmapinfoheader and palette if available ---
; get number of bytes to allocate for the palette in eax
; eax=0 if no palette (full color image or 16-bit color)
invoke GetDeviceCaps, hDC, BITSPIXEL
mov ecx, eax
.IF ecx<16
xor eax, eax
inc eax
shl eax, cl
shl eax, 2
.ELSE
xor eax, eax
.ENDIF
; add size of BITMAPINFOHEADER
add eax, SIZEOF BITMAPINFOHEADER
mov HeaderAndPaletteSize, eax
; allocate memory
invoke GlobalAlloc, GMEM_MOVEABLE or GMEM_ZEROINIT, eax
mov hTempMem, eax
invoke GlobalLock, eax
mov pTempMem, eax
mov ebx, pTempMem
;Get bitmapinfoheader:
assume ebx:PTR BITMAPINFOHEADER
mov .biSize, SIZEOF BITMAPINFOHEADER
invoke GetDIBits, hDC, hBitmap, 0, 0, NULL, ebx, DIB_RGB_COLORS
; Get size of image data:
mov eax, .biSizeImage
; allocate memory for image data:
invoke GlobalAlloc, GMEM_MOVEABLE, eax
mov hImageMem, eax
invoke GlobalLock, eax
mov pImageMem, eax
; get image data and full bitmap info header + palette if available:
mov ecx, .biHeight
invoke GetDIBits, hDC, hBitmap, 0, ecx, pImageMem, pTempMem, DIB_RGB_COLORS
; write header and palette to file
invoke WriteFile, hFile, pTempMem, HeaderAndPaletteSize, ADDR BytesWritten, 0
.IF eax==0
mov retval, eax
jmp @return1
.ENDIF
; write image data to file:
invoke WriteFile, hFile, pImageMem, .biSizeImage, ADDR BytesWritten, 0
.IF eax==0
mov retval, eax
jmp @return1
.ENDIF
;fill bitmapfileheader:
mov bfh.bfType, "MB" ;"BM", reversed
mov eax, HeaderAndPaletteSize
add eax, SIZEOF BITMAPFILEHEADER
mov bfh.bfOffBits, eax
add eax, .biSizeImage
mov bfh.bfSize, eax
and bfh.bfReserved1, 0
and bfh.bfReserved2, 0
;write bitmapfileheader:
invoke SetFilePointer, hFile, 0, 0, FILE_BEGIN
invoke WriteFile, hFile, ADDR bfh, SIZEOF BITMAPFILEHEADER, ADDR BytesWritten, 0
.IF eax==0
mov retval, eax
jmp @return1
.ENDIF
mov retval, 1
assume ebx:nothing
@return1:
;--- clear memory handles ---
invoke GlobalUnlock, hTempMem
invoke GlobalFree, hTempMem
invoke GlobalUnlock, hImageMem
invoke GlobalFree, hImageMem
;--- Close file handle ---
invoke CloseHandle, hFile
mov eax, retval
ret
SaveDCToBitmap endp
I don't know if it works perfectly for all color formats, paint had some troubles with reading the bitmap when it's a 16-bit or 32-bit color image. 8-bit and 24-bit worked fine.
But paint shop pro read all the bitmaps the program wrote.
Hope this helps,
Thomas