Assembly 基于像素到点x,y距离的平方,在其原始颜色和白色之间线性插值像素颜色
在以下任务中,我需要帮助理解线性插值的正确算法: 将24 bpp.BMP图像淡入白色,使每个像素的颜色根据其距离x坐标和y坐标指定的点的平方在其原始颜色和白色之间线性插值。假设x,y位于图像中。平方距离>=距离的像素不会褪色 我需要在x86汇编中实现它 我的想法是,我需要做以下事情:Assembly 基于像素到点x,y距离的平方,在其原始颜色和白色之间线性插值像素颜色,assembly,x86,linear-interpolation,Assembly,X86,Linear Interpolation,在以下任务中,我需要帮助理解线性插值的正确算法: 将24 bpp.BMP图像淡入白色,使每个像素的颜色根据其距离x坐标和y坐标指定的点的平方在其原始颜色和白色之间线性插值。假设x,y位于图像中。平方距离>=距离的像素不会褪色 我需要在x86汇编中实现它 我的想法是,我需要做以下事情: 计算具有坐标(x,y)的某些像素(点)与参考像素(xr,yr)之间的距离差。为此,我需要计算dx=| xr-x |,还有dy=| yr-y |,然后计算dx^2和dy^2,所以实际上我不需要dx和dy的绝对值 计
- 计算具有坐标(x,y)的某些像素(点)与参考像素(xr,yr)之间的距离差。为此,我需要计算dx=| xr-x |,还有dy=| yr-y |,然后计算dx^2和dy^2,所以实际上我不需要dx和dy的绝对值
- 计算d^2=dx^2+dy^2
- 然后使用合适的算法计算像素的颜色
section .text
global _sunfade
; arguments
%define img [ebp+8]
%define width [ebp+12]
%define height [ebp+16]
%define dist [ebp+20]
%define xc [ebp+24]
%define yc [ebp+28]
; local variables
%define row_bytes [ebp-4]
%define dx_2 [ebp-8]
%define dy_2 [ebp-12]
%define d_2 [ebp-16]
%define lvl [ebp-20]
%define x [ebp-24]
%define y [ebp-28]
%define dist_2 [ebp-32]
_sunfade:
; stack frame
push ebp
mov ebp, esp
sub esp, 32
; save required registers
push ebx
push esi
push edi
; source image data address
mov esi, img
; calculate row size
mov eax, width ; row size in pixels
imul eax, 3 ; row size* in bytes (3 bytes per pixel)
add eax, 3 ; 3 is the maximum value to fit on 2 least sign. bits
and eax, 0fffffffch ; zero out 2 least sign. bits, to round up to multiple of 4
mov row_bytes, eax ; row size in bytes (multiple of 4, padding handled)
; source pixels data address
add esi, 54
; lines counter
mov ecx, height ; ecx stores lines amount left
;=================================================================================================
; ------------ Begining of the algorithm ----------------
_line:
; line pixel count - pixels left to proceed
mov edi, width ; set / restet pixels to proceed
; counter of pixels left to procede in a line
; pixel index in a line - current pixel
xor ebx, ebx ; reset index
; ebx = x
_fade:
push edx
push ebx
xor edx, edx
mov eax, ebx
mov ebx, 3
div ebx
mov x, eax ; x coordnate
mov eax, height
sub eax, ecx ; y = height - lines amount left
mov y, eax ; y coordinate
mov eax, xc
sub eax, x ; eax = dx = xc - x
imul eax, eax ; eax = dx^2 (dx * dx)
mov dx_2, eax ; dx_2 = dx^2
mov eax, yc
sub eax, y ; eax = dy = yc -y
imul eax, eax ; eax = dy^2 (dy * dy)
mov dy_2, eax ; dy_2 = dy^2
mov eax, dist
imul eax, eax ; eax = dist^2 (dist * dist)
mov dist_2, eax
pop ebx
pop edx
mov eax, dx_2
add eax, dy_2 ; eax = (dx^2 +dy^2)
mov d_2, eax ; d_2 = d^2 = (dx^2 +dy^2)
cmp eax, dist_2 ; d^2 - dist^2
jae _next_pix ; if d^2 >= dist^2 then jump to _next_pix, to not change color of this pixel
xor edx, edx
;=================================================================================================
; ---------- PIXEL OPERATIONS START ----------
; saving counters
push ecx ; counter of lines to proceed
push ebx ; pixel index in a line - current pixel
mov eax, d_2
mov ebx, dist_2
div ebx ; eax = d^2 / dist^2
mov ebx, 1
sub ebx, eax ; fading coeficient = 1 - (d^2 / dist^2)
;mov eax, 256
;imul ebx, eax
mov ecx, ebx ; ecx = fading coefficient
pop ebx
;pop eax
movzx edx, byte [esi+ebx+0] ; getting the current color (its Blue coefficient)
mov eax, edx ; eax current color
imul eax, ecx ; fadded color = current collor * fading coefficient
;add eax, ecx
;shr eax, 1
;add eax, edx
mov [esi+ebx+0], al ; saving faded color (its Blue coefficient)
;=================================================================================================
push ebx ; pixel index in a line - current pixel
mov eax, d_2
mov ebx, dist_2
div ebx ; eax = d^2 / dist^2
mov ebx, 1
sub ebx, eax ; fading coeficient = 1 - (d^2 / dist^2)
;mov eax, 256
;imul ebx, eax
mov ecx, ebx ; ecx = fading coefficient
pop ebx
movzx edx, byte [esi+ebx+1] ; getting the current color (its Green coefficient)
mov eax, edx ; dx = current color
imul eax, ecx ; fadded color = current collor * fading coefficient
;add eax, ecx
;shr eax, 1
;add eax, edx
mov [esi+ebx+1], al ; saving faded color (its Green coefficient)
;=================================================================================================
push ebx ; pixel index in a line - current pixel
mov eax, d_2
mov ebx, dist_2
div ebx ; eax = d^2 / dist^2
mov ebx, 1
sub ebx, eax ; fading coeficient = 1 - (d^2 / dist^2)
;mov eax, 256
;imul ebx, eax
mov ecx, ebx ; ecx = fading coefficient
pop ebx
movzx edx, byte [esi+ebx+2] ; getting the current color (its Red coefficient)
mov eax, edx ; dx = current color
imul eax, ecx ; fadded color = current collor * fading coefficient
;add eax, ecx
;shr eax, 1
;add eax, edx
mov [esi+ebx+2], al ; saving faded color (its Red coefficient)
pop ecx
;=================================================================================================
; ---------- PIXEL OPERATIONS END ----------
_next_pix:
add ebx, 3 ; next pixel
dec edi ; decrement pixels left to proceed in a line
jnz _fade ; if not 0, continue to next pixel in a line
add esi, row_bytes ; advance address to next line
dec ecx ; decrement lines to proceed amount
jnz _line ; if not 0, continut to next line
; restore registers
pop edi
pop esi
pop ebx
; remove stack frame
mov esp, ebp
pop ebp
; return from procedure
ret
它正确地选择了用于改变像素颜色的区域,但是颜色发生了变化,并且没有褪色。我的淡入淡出算法不正确
你知道正确的算法会是什么样子吗
编辑2:
一种颜色的代码更改部分:
; ---------- PIXEL OPERATIONS START ----------
; saving counters
push ecx ; counter of lines to proceed
push ebx ; pixel index in a line - current pixel
mov eax, d_2
mov ebx, dist_2
div ebx ; eax = d^2 / dist^2
mov ebx, 1
sub ebx, eax ; fading coeficient = 1 - (d^2 / dist^2)
mov eax, 256
imul ebx, eax ; ebx = fading coefficient * 256
mov ecx, ebx ; ecx = fading coefficient
pop ebx
movzx edx, byte [esi+ebx+0] ; getting the current color (its Blue coefficient)
mov eax, edx ; eax current color
imul eax, ecx ; fadded color = current collor * fading coefficient
shr eax, 8 ; faded color / 256
add eax, edx ; new_color = current_color + (faded color/256)
mov [esi+ebx+0], al ; saving faded color (its Blue coefficient)
编辑3
再次更改一种颜色的零件:
但它不起作用。。。当我试图运行它时,程序停止工作
编辑4
它不起作用,因为我意外删除了pop ecx指令。。。
现在它正在绘制,smth类似于圆,但拉伸到右上角方向和左下角方向。它有许多不同颜色的线条。嗯,很难描述它的样子:P
; ---------- PIXEL OPERATIONS START ----------
; saving counters
push ecx ; counter of lines to proceed
push ebx ; pixel index in a line - current pixel
mov eax, d_2
shl eax, 8 ; eax = d_2 * 256
mov ebx, dist_2
div ebx ; eax = (d^2 * 256 ) / dist^2
mov ebx, 256
sub ebx, eax ; fading coeficient = 256 - [(d^2 * 256) / dist^2)]
mov ecx, ebx ; ecx = fading coefficient
pop ebx
movzx edx, byte [esi+ebx+0] ; getting the current color (its Blue coefficient)
mov eax, edx ; eax current color
imul eax, ecx ; fadded color = current collor * fading coefficient
shr eax, 8 ; faded color / 256
add eax, edx ; new_color = current_color + (faded color/256)
mov [esi+ebx+0], al ; saving faded color (its Blue coefficient)
imul eax,ecx
将当前信道值乘以衰落系数,这是(或应该是?)一个介于0到255之间的值,实际上是一个分数,乘以256。因此,在返回存储之前,必须将结果再次除以256以使其回到有效范围。目前,您存储的是最低、最低有效的8位。谢谢您的回答:)我只存储了8位,因为这是一个24 bmp位图,所以像素的每种颜色R、G、B都存储在总共24位中的8位中,对吗?你说得对。。但是乘法将结果“向上”移动256倍。你应该乘以一个介于0和1之间的因子,但它是“乘以256”,所以它适合整数寄存器。哦,是的。这是真的:)所以当我把它乘以256,然后除以256,它应该在8个低位?看看修改过的代码。啊——我想我找到了你错误的根源。不能在常规寄存器中进行除法(d/dist)——它们都是整数!改用(d*256/dist)。现在你的mul是256,跟在师后面,现在修它已经太迟了。哦,好吧,我试着这样做,但是smth是错的。