Альфа-смешивание вручную пикселя RGBA с пикселем RGB - PullRequest
21 голосов
/ 26 января 2012

Я пытаюсь выполнить операцию альфа-наложения изображения RGBA (изображение переднего плана) на изображении RGB (фоновое изображение).Однако, делая это, я думаю, что я могу делать неправильную операцию альфа-смешивания или делать это неправильно.Например, пиксель моего изображения RGB сероватого цвета (127, 127, 127).Пиксель моего изображения RGBA для пикселя будет (0, 0, 255).После того, как я сделаю операцию смешивания, окончательный цвет будет (127, 0, 255).Однако я подумал, что это скорее аддитивная смесь и отличается от операции, которую я делаю.

Чтобы узнать, как мои значения установлены, взгляните на это

incPixelColor[0] = 0; (red)
incPixelColor[1] = 0; (green)
incPixelColor[2] = 255; (blue)
incPixelColor[3] = 255; (alpha)

currentPixelColor[0] = 127; (red)
currentPixelColor[1] = 127; (green)
currentPixelColor[2] = 127; (blue)

Как моирасчет установлен, посмотрите на это

float incAlpha = (currentPixelColor[3]/255.0f);

float red = ((float)incPixelColor[0]/255.0f * incAlpha) + ((float)currentPixelColor[0]/255.0f);
float green = ((float)incPixelColor[1]/255.0f * incAlpha) + ((float)currentPixelColor[1]/255.0f);
float blue = ((float)incPixelColor[2]/255.0f * incAlpha) + ((float)currentPixelColor[2]/255.0f);


currentPixelColor[0] = min(red * 255, 255.0f);
currentPixelColor[1] = min(green * 255, 255.0f);
currentPixelColor[2] = min(blue * 255, 255.0f);

Для пикселей без альфа, я хотел бы, чтобы значение было (0, 0, 255), а затем для изображений с альфа, я хотел бы, чтобы этосмешайте. В конце описанной выше операции это будет (127, 127, 255).Должен ли я проверить, есть ли альфа для каждого пикселя, и если да, то выполнить смешение или есть другой способ сделать это?

Ответы [ 3 ]

25 голосов
/ 26 января 2012

Типичная смесь "Over" выполняется следующим образом:

outputRed = (foregroundRed * foregroundAlpha) + (backgroundRed * (1.0 - foregroundAlpha));

А затем повторить для синих и зеленых каналов. Сделайте это для каждого пикселя.

2 голосов
/ 26 января 2012

Похоже, вы пропустили (1-альфа) множитель для фона (currentPixelColor)

1 голос
/ 13 апреля 2018

alpha_blend_sse :)

;example usage
;mov eax, 0xabcdef
;mov edx, 0xAAAAAADD
;call alph_blend_see


; In\   EAX = background color (ZRBG) 32bit (Z mean zero, always is zero)
; In\   EDX = foreground color (RBGA) 32bit
; Out\  EAX = new color
alph_blend_sse:
    xor r14, r14
    xor r12, r12
    xor r13, r13

    movzx r15, dl               ; av: alpha number (0x00--->0xFF)
    movzx ecx, dl
    not ecx                     ; faster than 255 - dl
    mov r14b, cl                ; rem

    shr edx, 8
    and edx, 0x00FFFFFF
    mov r12d, edx
    mov r13d, eax               ; RBGA ---> ZRGB

    mov rax, 0x0000FF
    movq xmm3, rax

    ; s: eax
    ; d: edx

    ;=============================red = ((s >> 16) * rem + (d >> 16) * av) >> 8;
    movq xmm0, r12
    psrld xmm0, 0x10
    movq xmm1, r14
    pmuludq xmm1, xmm0
    movq xmm0, r13
    psrld xmm0, 0x10
    movq xmm2, r15
    pmuludq xmm2, xmm0
    addps xmm2, xmm1
    psrld xmm2, 0x8
    movq rax, xmm2
    mov r9b, al
    shl r9d, 8

    ;=============================green = (((s >> 8) & 0x0000ff) * rem + ((d >> 8) & 0x0000ff) * av) >> 8;
    movq xmm0, r12
    psrld xmm0, 0x8
    andps xmm0, xmm3
    movq xmm1, r14
    pmuludq xmm1, xmm0
    movq xmm0, r13
    psrld xmm0, 0x8
    andps xmm0, xmm3
    movq xmm2, r15
    pmuludq xmm2, xmm0
    addps xmm2, xmm1
    psrld xmm2, 0x8
    movq rax, xmm2
    mov r9b, al
    shl r9d, 8

    ;=============================blue = ((s & 0x0000ff) * rem + (d & 0x0000ff) * av) >> 8;
    movq xmm0, r12
    andps xmm0, xmm3
    movq xmm1, r14
    andps xmm1, xmm3
    pmuludq xmm1, xmm0
    movq xmm0, r13
    andps xmm0, xmm3
    movq xmm2, r15
    andps xmm2, xmm3
    pmuludq xmm2, xmm0
    addps xmm2, xmm1
    psrld xmm2, 0x8
    movq rax, xmm2
    mov r9b, al

    mov eax, r9d
    ret
...