Создание .BMP

 


В который раз взялся за сохранение .bmp и вышла неразбериха. Взял пример с форума Flat Assembler

; ;https://board.flatassembler.net/topic.php?t=13462
;Windows BMP files header
;https://www.file-recovery.com/bmp-signature-format.htm

; bmpHeader:              ; 54 bytes
;         Signature       db 0x42,0x4D,0xC6,0x5F,0x01,00,00,00,00,00,0x36,00,00,00        ; 14 bytes
;         bi24BitInfo     BITMAPINFO                                                      ; 40 bytes
;         ; Initialize bitmapinfo
bmiHeader.BITMAPINFOHEADER
bi24BitInfo.BITMAPINFO
bi24BitInfo\bmiHeader\biSize=SizeOf(BITMAPINFOHEADER)
bi24BitInfo\bmiHeader\biWidth=800
bi24BitInfo\bmiHeader\biHeight=600
bi24BitInfo\bmiHeader\biPlanes=1
bi24BitInfo\bmiHeader\biBitCount=24
bi24BitInfo\bmiHeader\biCompression=0
bi24BitInfo\bmiHeader\biSizeImage=$15f900;1440000
memDC=CreateCompatibleDC_(0)
hDIB=CreateDIBSection_(memDC, @bi24BitInfo, 0, @pbits, 0, 0)
SelectObject_(memDC,hDIB)
winDC=GetDC_(0)
StretchBlt_(memDC, 0, 0, 800, 600, winDC, 0, 0, 1152, 864, #SRCCOPY)
CreateFile(0,"huj.bmp")
;         invoke WriteFile, eax, bmpHeader, 54, bWritten, 0
PokeL (?bmSignature+2,1440054)
WriteData(0,?bmSignature,14)
WriteData(0,@bi24BitInfo,SizeOf(BITMAPINFO)-4)
;Debug SizeOf(BITMAPINFO)=44?
; 1440000 = 800 * 600 * 3
WriteData(0,pbits,1440000)
CloseFile(0) 
DeleteDC_(memDC)
DeleteObject_(hDIB)
ReleaseDC_(@HWND_DESKTOP,winDC)
DataSection
  bmSignature:
  Data.a $42,$4D,$C6,$5F,$01,00,00,00,00,00,$36,00,00,00        ; 14 bytes
  ;1440054 must be $C6,$5F,$01

Один баг в размере структуры BITMAPINFO. Почему-то вышло 44 байта, а не 40. По описанию структуры должно быть 40, но компилятору нравится другое число. Хрен разберешь.

Дополнение. Ступил немного:
; ;https://board.flatassembler.net/topic.php?t=13462
;Windows BMP files header
;https://www.file-recovery.com/bmp-signature-format.htm
; bmpHeader:              ; 54 bytes
;         Signature       db 0x42,0x4D,0xC6,0x5F,0x01,00,00,00,00,00,0x36,00,00,00        ; 14 bytes
;         bi24BitInfo     BITMAPINFO                                                      ; 40 bytes

;Initialize bitmapinfo
sw=GetSystemMetrics_(#SM_CXSCREEN)
sh=GetSystemMetrics_(#SM_CYSCREEN)

bmiHeader.BITMAPINFOHEADER
bi24BitInfo.BITMAPINFO

bi24BitInfo\bmiHeader\biSize=SizeOf(BITMAPINFOHEADER)
bi24BitInfo\bmiHeader\biWidth=sw
bi24BitInfo\bmiHeader\biHeight=sh
bi24BitInfo\bmiHeader\biPlanes=1
bi24BitInfo\bmiHeader\biBitCount=24
bi24BitInfo\bmiHeader\biCompression=0
bi24BitInfo\bmiHeader\biSizeImage=sw*sh*3

memDC=CreateCompatibleDC_(0)
hDIB=CreateDIBSection_(memDC, @bi24BitInfo, 0, @pbits, 0, 0)
SelectObject_(memDC,hDIB)
winDC=GetDC_(0)
BitBlt_(memDC, 0, 0, sw, sh, winDC, 0, 0, #SRCCOPY)

CreateFile(0,"dsktop.bmp")

PokeL (?bmSignature+2,sw*sh*3+54)
WriteData(0,?bmSignature,14)
WriteData(0,@bi24BitInfo,SizeOf(BITMAPINFOHEADER))

;Debug SizeOf(BITMAPINFO)=44?

WriteData(0,pbits,sw*sh*3)
CloseFile(0) 

DeleteDC_(memDC)
DeleteObject_(hDIB)
ReleaseDC_(#HWND_DESKTOP,winDC)

DataSection
  bmSignature:
  Data.a $42,$4D,$C6,$5F,$01,00,00,00,00,00,$36,00,00,00        ; 14 bytes

Дополнение 2 .Раскопал незавершенный код рисования на картинке и дополнил до конца - очистка после завершения рисования, корректные значения структур
Structure POINTTRIANGLE 
  pointA.POINT 
  pointB.POINT 
  pointC.POINT 
  pointD.POINT 
EndStructure 

x1=100
y1=10
x2=10
y2=180
x3=180
y3=180

triangle.POINTTRIANGLE 
triangle\pointA\x = x1 
triangle\pointA\y = y1 
triangle\pointB\x = x2 
triangle\pointB\y = y2 
triangle\pointC\x = x3 
triangle\pointC\y = y3 
triangle\pointD\x = x1 
triangle\pointD\y = y1 


hwnd=GetDesktopWindow_()
HHDC=GetWindowDC_( hwnd );0
hdc=CreateCompatibleDC_(HHDC)
hbmp=CreateCompatibleBitmap_(hhdc,200,200)

SelectObject_(hDC,hbmp)
;draw triangle
hPen.l=CreatePen_( #PS_SOLID,2,RGB(255,0,0) )
hBrush.l=CreateSolidBrush_(RGB(0,255,0))
SelectObject_(hDC,hBrush)
SelectObject_(hDC,hPen)
Polygon_( hDC, @triangle, 4 )
DeleteObject_(hBrush)
DeleteObject_(hPen)
;draw text
r.RECT
r\left=0
r\right=200
r\top=100
r\bottom=200
SetBkMode_(hDC,#TRANSPARENT)
SetTextColor_(hDC,RGB(255,0,255))
DrawText_(hDC,@"Tri",3,@r,#DT_CENTER )


GetObject_(hbmp, SizeOf(BITMAP), bm.BITMAP)

bmi.BITMAPINFO
bmi\bmiHeader\biSize=SizeOf(BITMAPINFOHEADER)
bmi\bmiHeader\biWidth=bm\bmWidth
bmi\bmiHeader\biHeight=bm\bmHeight
bmi\bmiHeader\biPlanes=1
bmi\bmiHeader\biBitCount=24;;32
bmi\bmiHeader\biCompression=#BI_RGB
bmi\bmiHeader\biClrUsed=24;;32

DataSize=bm\bmWidth*bm\bmHeight*3
*m=AllocateMemory(DataSize)
bmi\bmiHeader\biSizeImage=DataSize

If GetDIBits_(hDC, hbmp, 0, bm\bmHeight, *m, bmi, #DIB_RGB_COLORS)
  pbfh_.BITMAPFILEHEADER
  pbfh_\bfType=$4d42
  pbfh_\bfSize=bm\bmWidth*bm\bmHeight*3+SizeOf(BITMAPFILEHEADER)+SizeOf(BITMAPINFOHEADER)
  pbfh_\bfReserved1=0
  pbfh_\bfReserved2=0
  pbfh_\bfOffBits=SizeOf(BITMAPFILEHEADER)+SizeOf(BITMAPINFOHEADER)
  
  CreateFile(0,"drw.bmp")
  
  WriteData(0,pbfh_,SizeOf(BITMAPFILEHEADER))
  WriteData(0,bmi,SizeOf(BITMAPINFOHEADER))
  WriteData(0,*m,DataSize)
  CloseFile(0)
  
Else
  Debug "oops"
EndIf

;clean up
FreeMemory(*m)
ReleaseDC_(hwnd,HHDC)
DeleteDC_(hdc)
DeleteObject_(hbmp)

Файлы тут.



Комментарии