I am trying to do an alpha blend operation of an RGBA image (foreground image), on to a RGB image (background image). However, while doing so I think I may be doing the wrong alpha blending operation or doing it wrong. For example, the pixel of my RGB image is a grayish color of (127, 127, 127). The pixel of my RGBA image for the pixel will be (0, 0, 255). After I do my blending operation, the final color will be (127, 0, 255). However, I thought that was more of an additive blend and different than the operation I am doing.
For how my values are set, take a look at this
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)
For how my calculation is set, take a look at this
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);
For pixels with no alpha, I would like for the value to be (0, 0, 255) then for images with alpha I would like for it to blend in. At the end of the operation above, it will be (127, 127, 255). Should I check to see if there is alpha for every pixel, and if so, then do the blend or is there another way to do this?
A typical "Over" blend is done in the following way:
outputRed = (foregroundRed * foregroundAlpha) + (backgroundRed * (1.0 - foregroundAlpha));
And then repeating for the blue and green channels. Do this for every pixel.
It seems that you have missed out (1-Alpha) multiplier for background (currentPixelColor)
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
来源:https://stackoverflow.com/questions/9014729/manually-alpha-blending-an-rgba-pixel-with-an-rgb-pixel