# alpha_composite() 图像数据之处理方法细节

## 2. 问题内容

### 问题二: alpha_composite()是如何计算两张图像alpha值, 而得到新图层alpha值 ?

#### 注: 下方提供图像pixel值及alpha值数据供参考 (以R band + alpha为例, 僅列出部份值供对比用)

[001, 000, 000, 000, 255, 254, 255, 254, 255, 255, ... , 254]

[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, ... , 255]

[254, 255, 254, 255, 254, 255, 003, 000, 000, 254, ... , 255]

[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, ... , 255]

[254, 255, 254, 255, 254, 255, 003, 000, 000, 254, ... , 255]

[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, ... , 255]

[001, 000, 000, 000, 255, 254, 255, 254, 255, 255, ... , 254]

[001, 001, 001, 001, 001, 001, 001, 001, 001, 001, ... , 001]

[254, 255, 254, 255, 254, 255, 003, 000, 000, 254, ... , 255]

[001, 001, 001, 001, 001, 001, 001, 001, 001, 001, ... , 001]

[128, 128, 127, 128, 254, 254, 129, 127, 127, 254, ... , 254]

[002, 002, 002, 002, 002, 002, 002, 002, 002, 002, ... , 002]

``````### alpha_composite() 图像数据之处理方法细节

filename1 = "D:/图001.jpg"
filename2 = "D:/图002.jpg"

from PIL import Image

# Open two image jpg file
im1 = Image.open(filename1)
im2 = Image.open(filename2)

# Convert RBG to RGBA format to be with alpha band
im3 = im1.convert("RGBA")
im4 = im2.convert("RGBA")

# Alpha composite im4 over im3, then show the result 图003
result_im = Image.alpha_composite(im3, im4)
result_im.show()

# fill all alpha data in im3 and im4 with 1
im3.putalpha(1)
im4.putalpha(1)

# Alpha composite im4 over im3, then show the result 图004
result_im = Image.alpha_composite(im3, im4)
result_im.show()``````
Jason Yang

## Image.alpha_composite(im1, im2) 工作原理如下:+1:

``````"""
algorithm of alpha_composite method: r2 over r1

r1, r2: pixel data
a1, a2: alpha data

factor_pixel = a2/(a2 + a1 * (1.0 - a2/ 255.0))
new_pixel = r2 * factor_pixel + r1 * (1 - factor_pixel)

factor_alpha = 1.0 - a2/255.0
new_alpha = a2 + a1 * factor_alpha

conclusion: Here, same method used for all three methods, but different
method implemented. Method 3 is used in Python PIL, so same result as
the data for confirmation. For method 2 and 3, it is caused by the iteration
error on interger and float number, but just small error 1.

"""

# list1 is destination image data
# list2 is source image data
# list3 is the final image data after Image.alpha_composite(destination_image, source_image)

list1_pixel = [1,0,0,0,255,254,255,254,255,255,254,
1,0,0,0,255,254,255,254,255,255,254]
list1_alpha = [255,255,255,255,255,255,255,255,255,
255,255,1,1,1,1,1,1,1,1,1,1,1]
list2_pixel = [254,255,254,255,254,255,3,0,0,254,255,
254,255,254,255,254,255,3,0,0,254,255]
list2_alpha = [255,255,255,255,255,255,255,255,255,255,
255,1,1,1,1,1,1,1,1,1,1,1]
list3_pixel = [254,255,254,255,254,255,3,0,0,254,255,
128,128,127,128,254,254,129,127,127,254,254]
list3_alpha = [255,255,255,255,255,255,255,255,255,255,
255,2,2,2,2,2,2,2,2,2,2,2]

# method 1

error = 0
item_different = 0

list_pixel = []
list_alpha = []

for index in range(len(list1_pixel)):
dsta = list1_alpha[index] / 255.0
srca = list2_alpha[index] / 255.0
blend = dsta * (1.0 - srca)
outa = srca + blend
coef1 = srca / outa
coef2 = 1 - coef1
tmpr = list2_pixel[index] * coef1 + list1_pixel[index] * coef2
pixel = int(tmpr + 0.5)
alpha = int(outa * 255.0 + 0.5)
list_pixel.append(pixel)
list_alpha.append(alpha)
difference1 = abs(pixel - list3_pixel[index])
difference2 = abs(alpha - list3_alpha[index])
error = error + difference1+ difference2
if difference1:
item_different += 1
if difference2:
item_different += 1

print("Method 1:")
print(item_different, "wrong items, the total differences counted:",error)

# method 1

error = 0
item_different = 0

list_pixel = []
list_alpha = []

for index in range(len(list1_pixel)):
factor_pixel = list2_alpha[index] / (list2_alpha[index] + \
list1_alpha[index] * (1.0 - list2_alpha[index]/ 255.0))
pixel = list2_pixel[index] * factor_pixel + \
list1_pixel[index]*(1 - factor_pixel)
pixel = int(pixel + 0.5)
factor_alpha = 1.0 - list2_alpha[index]/ 255.0
alpha = list2_alpha[index] + list1_alpha[index] * factor_alpha
alpha = int(alpha + 0.5)
list_pixel.append(pixel)
list_alpha.append(alpha)
difference1 = abs(pixel - list3_pixel[index])
difference2 = abs(alpha - list3_alpha[index])
error = error + difference1+ difference2
if difference1:
item_different += 1
if difference2:
item_different += 1

print("Method 2:")
print(item_different, "wrong items, the total differences counted:",error)

# method 3

error = 0
item_different = 0

list_pixel = []
list_alpha = []

tmpr = 0
outa255 = 0

for index in range(len(list1_pixel)):
blend = list1_alpha[index] * (255 - list2_alpha[index])
outa255 = list2_alpha[index] * 255 + blend
coef1 = list2_alpha[index] * 255 * 255 * 128 / outa255
coef2 = 255 * 128 - coef1
right8 = lambda a: ((int(a)>>8)+int(a)>>8)
tmpr = list2_pixel[index] * coef1 + list1_pixel[index] \
* coef2 + (0x80 << 7)
pixel = right8(tmpr) >> 7
alpha = right8(outa255 + 0x80);
list_pixel.append(pixel)
list_alpha.append(alpha)
difference1 = abs(pixel - list3_pixel[index])
difference2 = abs(alpha - list3_alpha[index])
error = error + difference1 + difference2
if difference1 != 0:
item_different += 1
if difference2 != 0:
item_different += 1

print("Method 3")
print(item_different, "wrong items, the total differences counted:",error)``````
1年前 评论

## Image.alpha_composite(im1, im2) 工作原理如下:+1:

``````"""
algorithm of alpha_composite method: r2 over r1

r1, r2: pixel data
a1, a2: alpha data

factor_pixel = a2/(a2 + a1 * (1.0 - a2/ 255.0))
new_pixel = r2 * factor_pixel + r1 * (1 - factor_pixel)

factor_alpha = 1.0 - a2/255.0
new_alpha = a2 + a1 * factor_alpha

conclusion: Here, same method used for all three methods, but different
method implemented. Method 3 is used in Python PIL, so same result as
the data for confirmation. For method 2 and 3, it is caused by the iteration
error on interger and float number, but just small error 1.

"""

# list1 is destination image data
# list2 is source image data
# list3 is the final image data after Image.alpha_composite(destination_image, source_image)

list1_pixel = [1,0,0,0,255,254,255,254,255,255,254,
1,0,0,0,255,254,255,254,255,255,254]
list1_alpha = [255,255,255,255,255,255,255,255,255,
255,255,1,1,1,1,1,1,1,1,1,1,1]
list2_pixel = [254,255,254,255,254,255,3,0,0,254,255,
254,255,254,255,254,255,3,0,0,254,255]
list2_alpha = [255,255,255,255,255,255,255,255,255,255,
255,1,1,1,1,1,1,1,1,1,1,1]
list3_pixel = [254,255,254,255,254,255,3,0,0,254,255,
128,128,127,128,254,254,129,127,127,254,254]
list3_alpha = [255,255,255,255,255,255,255,255,255,255,
255,2,2,2,2,2,2,2,2,2,2,2]

# method 1

error = 0
item_different = 0

list_pixel = []
list_alpha = []

for index in range(len(list1_pixel)):
dsta = list1_alpha[index] / 255.0
srca = list2_alpha[index] / 255.0
blend = dsta * (1.0 - srca)
outa = srca + blend
coef1 = srca / outa
coef2 = 1 - coef1
tmpr = list2_pixel[index] * coef1 + list1_pixel[index] * coef2
pixel = int(tmpr + 0.5)
alpha = int(outa * 255.0 + 0.5)
list_pixel.append(pixel)
list_alpha.append(alpha)
difference1 = abs(pixel - list3_pixel[index])
difference2 = abs(alpha - list3_alpha[index])
error = error + difference1+ difference2
if difference1:
item_different += 1
if difference2:
item_different += 1

print("Method 1:")
print(item_different, "wrong items, the total differences counted:",error)

# method 1

error = 0
item_different = 0

list_pixel = []
list_alpha = []

for index in range(len(list1_pixel)):
factor_pixel = list2_alpha[index] / (list2_alpha[index] + \
list1_alpha[index] * (1.0 - list2_alpha[index]/ 255.0))
pixel = list2_pixel[index] * factor_pixel + \
list1_pixel[index]*(1 - factor_pixel)
pixel = int(pixel + 0.5)
factor_alpha = 1.0 - list2_alpha[index]/ 255.0
alpha = list2_alpha[index] + list1_alpha[index] * factor_alpha
alpha = int(alpha + 0.5)
list_pixel.append(pixel)
list_alpha.append(alpha)
difference1 = abs(pixel - list3_pixel[index])
difference2 = abs(alpha - list3_alpha[index])
error = error + difference1+ difference2
if difference1:
item_different += 1
if difference2:
item_different += 1

print("Method 2:")
print(item_different, "wrong items, the total differences counted:",error)

# method 3

error = 0
item_different = 0

list_pixel = []
list_alpha = []

tmpr = 0
outa255 = 0

for index in range(len(list1_pixel)):
blend = list1_alpha[index] * (255 - list2_alpha[index])
outa255 = list2_alpha[index] * 255 + blend
coef1 = list2_alpha[index] * 255 * 255 * 128 / outa255
coef2 = 255 * 128 - coef1
right8 = lambda a: ((int(a)>>8)+int(a)>>8)
tmpr = list2_pixel[index] * coef1 + list1_pixel[index] \
* coef2 + (0x80 << 7)
pixel = right8(tmpr) >> 7
alpha = right8(outa255 + 0x80);
list_pixel.append(pixel)
list_alpha.append(alpha)
difference1 = abs(pixel - list3_pixel[index])
difference2 = abs(alpha - list3_alpha[index])
error = error + difference1 + difference2
if difference1 != 0:
item_different += 1
if difference2 != 0:
item_different += 1

print("Method 3")
print(item_different, "wrong items, the total differences counted:",error)``````
1年前 评论