使用Python图像库调整透明PNG大小和光晕效果
在StackOverflow上有几个类似的问题,但都没有真正帮到我。简单来说,我想调整一个简单的png图片的大小,具体可以看看这里:
http://media.spiralknights.com/wiki-images/3/3e/Equipment-Proto_Sword_icon.png (来自网络游戏《Spiral Knights》,版权归Three Rings Entertainment所有)
我最开始是用php实现了一个工具,使用这些图片,那个调整大小的工具效果很好。我用的是PHP文档中imagecopyresampled页面上描述的方法。
说实话,我在Photoshop里都没法调整得更好,而在python里结果几乎是灾难性的。我总是会出现光晕效果,我觉得这至少部分是因为透明像素的实际RGBA值。这里有张图片能更好地说明问题:
(倒数第二个调整大小是我在另一个论坛看到的建议,先调整到最终大小的两倍,确实有一点帮助,但还是不够)
在调整大小时,这张图片已经是RGBA模式了。
如你所见,PHP和Photoshop的调整没有光晕。老实说,除了PHP的调整以外,其他的都做得太过了,我喜欢php图片中的简约调色板(如果你看更大的版本,可以看到PHP调整使用了更少的中间颜色),但我也能接受Photoshop的调整,或者甚至是python调整的内部部分,但光晕是不可接受的。
我觉得——如果我错了请纠正我——PHP和Photoshop似乎知道在插值时不使用alpha通道中像素的颜色,而python却在调整时使用了那条本来是透明的浅边框。
不幸的是,我需要调整的图标有很多,形状各异,所以它们并不都是像这个圆形的那么简单,但这是我在实验时使用的第一个。
这本身并不是一个太复杂的代码问题,但如果你需要看点东西,这就是大致内容:
>> import Image
>> img = Image.open('swordorig.png')
>> img
<PngImagePlugin.PngImageFile image mode=RGBA size=256x256 at 0x2A3AF58>
>> img.resize((36,36), Image.ANTIALIAS).save('swordresize.png')
最终的问题是:有没有办法告诉PIL在重采样时不要使用alpha值为0的像素的颜色?
1 个回答
感谢大家的回答!特别感谢rotoglup告诉我我其实在找的是什么术语。在浏览关于PIL中预乘阿尔法的Stack Overflow页面时,我找到了一种有效的解决方案;这里是更新后的图形缩放表:
灰色条只是为了让大家能想象在更浅的背景下它们的样子。
https://stackoverflow.com/a/6882161/1189554
还要感谢madlag
所以我的代码最后看起来是这样的:
>> import Image, numpy
>> img = Image.open('swordorig.png')
>> premult = numpy.fromstring(img.tostring(), dtype=numpy.uint8)
>> alphaLayer = premult[3::4] / 255.0
>> premult[::4] *= alphaLayer
>> premult[1::4] *= alphaLayer
>> premult[2::4] *= alphaLayer
>> img = Image.fromstring("RGBA", img.size, premult.tostring())
>> img.resize((36,36), Image.ANTIALIAS).save('swordresize.png')
这样你就得到了图表底部的图标。颜色比PHP版本多了很多,还有一个很淡的边框,但整体上看起来好得多。我相信这个算法还可以调整得更好。再次感谢大家的回复!