Assembly 基于像素到点x,y距离的平方,在其原始颜色和白色之间线性插值像素颜色

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的绝对值 计

在以下任务中,我需要帮助理解线性插值的正确算法:

将24 bpp.BMP图像淡入白色,使每个像素的颜色根据其距离x坐标和y坐标指定的点的平方在其原始颜色和白色之间线性插值。假设x,y位于图像中。平方距离>=距离的像素不会褪色

我需要在x86汇编中实现它

我的想法是,我需要做以下事情:

  • 计算具有坐标(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是错的。