我正在开发一个读取 BMP 文件内容并在图像上执行平滑数字过滤器的项目。我下面的代码几乎可以完成这项工作。我只是不知道应该在哪里存储处理后的像素以及如何将处理后的图像写入文件。我下面的代码已被注释掉,因此我们将不胜感激任何帮助。
.586
.model flat, stdcall
option casemap :none
include ..\masm32\include\windows.inc
include ..\masm32\include\user32.inc
include ..\masm32\include\kernel32.inc
include ..\masm32\macros\macros.asm
include ..\masm32\include\masm32.inc
includelib ..\masm32\lib\user32.lib
includelib ..\masm32\lib\kernel32.lib
includelib ..\masm32\lib\masm32.lib
.data
FileName db "bitmap2.bmp", 0
filename db "bitmap_fil.bmp",0
errMsg BYTE "Cannot create file",0dh,0ah,0
hFile HANDLE ?
hwFile HANDLE ?
hMemory HANDLE ? ;incoming data
pMemory DWORD ?
hMemory_o HANDLE ? ;outgoing data
pMemory_o DWORD ?
ReadSize DWORD ?
bytesWritten DWORD ?
firstLine DWORD ?
FileSize DWORD ?
BDoff DWORD ?
BHSize DWORD ?
szTemp byte 16 dup (0) ;buffer for messages
szPrime byte "%08i", 0 ;message format string
szPrimeH byte "%08lx",0 ;message hexa format string
signature DD 0
MEMORYSIZE equ 65535 ;This is how much memory allocated
; to store the file.
im_offset dd ?
im_width dd ?
im_height dd ?
bits_pix dd ?
.code
;................................
show MACRO caption, value
print SADD(caption)
mov eax, value
invoke wsprintf, offset szTemp, offset szPrime, eax ;converts eax into string
print offset szTemp ;print string
print SADD(13,10)
ENDM
;..................................
start:
invoke CreateFile, addr FileName,GENERIC_READ,FILE_SHARE_READ,NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL
mov hFile, eax
;Allocate and lock the memory for incoming file.
invoke GlobalAlloc, GMEM_MOVEABLE or GMEM_ZEROINIT, MEMORYSIZE
mov hMemory, eax
invoke GlobalLock, hMemory
mov pMemory, eax
;Allocate and lock the memory for outgoing file.
invoke GlobalAlloc, GMEM_MOVEABLE or GMEM_ZEROINIT, MEMORYSIZE
mov hMemory_o, eax
invoke GlobalLock, hMemory_o
mov pMemory_o, eax
;Read file and save image parameters
invoke ReadFile, hFile, pMemory, MEMORYSIZE-1, addr ReadSize, NULL
mov esi, pMemory
add esi, 02 ;get filesize
mov edi, [esi]
mov FileSize,edi
invoke wsprintf, offset szTemp, offset szPrime, edi
print offset szTemp
print SADD(10,13)
add esi, 8 ; jump 8 bytes to get image offset
mov edi, [esi] ; get image offset
mov im_offset,edi
invoke wsprintf, offset szTemp, offset szPrimeH, edi
print offset szTemp
print SADD(10,13)
add esi,8 ;jump 8 bytes to get image width
mov edi, [esi] ; get image width
mov im_width, edi
invoke wsprintf, offset szTemp, offset szPrime, edi
print offset szTemp
print SADD(10,13)
add esi,4 ;jump 4 bytes to get image height
mov edi, [esi] ; get image height
mov im_height, edi
invoke wsprintf, offset szTemp, offset szPrime, edi
print offset szTemp
print SADD(10,13)
add esi,4 ;jump 4 bytes to get color plane
mov ebx, [esi]
shr ebx,16 ; get color plane and bit-pix
mov bits_pix,ebx ;
print SADD("bit-per-pix ")
invoke wsprintf, offset szTemp, offset szPrime, ebx
print offset szTemp
print SADD(10,13)
mov ebp, pMemory ; get ready to start processing the image
add ebp, im_offset ; esi now points to the first pix
;filtering process
;leave first row and first column and last row and last column untouched.
mov esi,1 ; esi is the row counter
mov edi,1 ; edi is the column counter
proc_pix:
;show "current column is: ",edi
;show "current row is: ",esi
xor ebx,ebx ; ebx = 0 ebx will accumulate intermediate values for averaging
mov eax, im_width ; eax is the pointer to the pixel
mul esi
add eax,edi
add ebx, [ebp+eax] ;get the pixel(I,J)
mov eax, im_width
add esi,1 ;next row (I+1)
mul esi
add eax,edi
add ebx, [ebp+eax] ;get the pixel(I+1,J)
mov eax, im_width
sub esi,2 ; prev row (I-1)
mul esi
add eax,edi
add ebx, [ebp+eax] ;get the pixel(I-1,J)
add esi,1 ;back to the current row
add edi,1 ;get next column (J+1)
mov eax, im_width
mul esi
add eax,edi
add ebx, [ebp+eax] ;get the pixel(I,J+1)
sub edi,2 ; get prev column (J-1)
mov eax, im_width
mul esi
add eax,edi
add ebx, [ebp+eax] ;get the pixel(I,J-1)
add edi,1 ;back current column
xor edx, edx ;clear upper part dividend
mov eax, ebx ; move data to eax to divide
mov ecx, 5
div ecx ;do the average (div 5)>>> result in eax
; where should I store the processed pixels?
inc edi ; do the next column
cmp edi, im_width
jl proc_pix
inc esi ; do the next row
mov edi,1 ; skip the first column
cmp esi, im_height
jl proc_pix
;....................................................................................
new_file:
invoke CreateFile,ADDR filename, GENERIC_WRITE, NULL, NULL,CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0
mov hwFile,eax ; save file handle
; handling of error if invalid file handle
cmp eax,INVALID_HANDLE_VALUE
jne writef
invoke StdOut, addr errMsg ; Display error message
jmp QuitNow
writef: invoke WriteFile, hwFile, pMemory_o, FileSize, ADDR bytesWritten, 0
QuitNow:
invoke GlobalUnlock, pMemory
invoke GlobalUnlock, pMemory_o
invoke GlobalFree, hMemory
invoke CloseHandle, hFile
invoke CloseHandle, hwFile
invoke ExitProcess, NULL
end start
;finish