假设您想要缩放透明图像,但还不知道稍后将其合成的背景颜色。不幸的是,PIL 似乎合并了完全透明像素的颜色值,导致了糟糕的结果。有没有办法告诉 PIL-resize 忽略完全透明的像素?
import PIL.Image
filename = "trans.png"
size = (25,25)
im = PIL.Image.open(filename)
print im.mode # RGBA
im = im.resize(size, PIL.Image.LINEAR) # the same with CUBIC, ANTIALIAS, transform
# im.show() # does not use alpha
im.save("resizelinear_"+filename)
# PIL scaled image has dark border
具有 (0,0,0,0)(黑色但完全透明)背景的原始图像(左)
带有黑色光晕的输出图像(中)
使用 gimp 缩放的正确输出(右)
看起来要实现我正在寻找的目标,我必须修改调整大小函数本身的采样,以便它忽略完全透明的像素。
我找到了一个非常丑陋的解决方案。它将完全透明像素的颜色值设置为周围非完全透明像素的平均值,以最大限度地减少调整大小时完全透明像素颜色的影响。简单的形式很慢,但如果没有其他解决方案,我会发布它。通过使用扩张操作仅处理必要的像素,可能可以使其更快。
看来 PIL 在调整大小之前不会进行 alpha 预乘,这是获得正确结果所必需的。幸运的是,通过暴力很容易做到。然后,您必须对调整大小的结果执行相反的操作。
def premultiply(im):
pixels = im.load()
for y in range(im.size[1]):
for x in range(im.size[0]):
r, g, b, a = pixels[x, y]
if a != 255:
r = r * a // 255
g = g * a // 255
b = b * a // 255
pixels[x, y] = (r, g, b, a)
def unmultiply(im):
pixels = im.load()
for y in range(im.size[1]):
for x in range(im.size[0]):
r, g, b, a = pixels[x, y]
if a != 255 and a != 0:
r = 255 if r >= a else 255 * r // a
g = 255 if g >= a else 255 * g // a
b = 255 if b >= a else 255 * b // a
pixels[x, y] = (r, g, b, a)
Result:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)