图像大师:优化我的 Python PNG 透明度功能
我需要用 Alpha 透明度替换 PNG 图像中的所有白色像素。
我在 AppEngine 中使用 Python,因此无法访问 PIL、imagemagick 等库。AppEngine 确实有一个图像库,但主要用于调整图像大小。
我发现了优秀的小 pyPNG 模块 并设法完成了一个小功能,可以完成以下任务我需要:
主循环的伪代码如下:
for each pixel:
if pixel looks "quite white":
set pixel values to transparent
otherwise:
keep existing pixel values
并且(假设8位值)“相当白色”将是:
where each r,g,b value is greater than "240"
AND each r,g,b value is within "20" of each other
这是我第一次以这种方式处理原始像素数据,虽然有效,但它的性能也非常差。似乎必须有一种更有效的方法来处理数据,而无需以这种方式迭代每个像素? (矩阵?)
我希望在处理这些事情方面有更多经验的人能够指出我的算法中的一些更明显的错误/改进。
谢谢!
I need to replace all the white(ish) pixels in a PNG image with alpha transparency.
I'm using Python in AppEngine and so do not have access to libraries like PIL, imagemagick etc. AppEngine does have an image library, but is pitched mainly at image resizing.
I found the excellent little pyPNG module and managed to knock up a little function that does what I need:
pseudo-code for the main loop would be something like:
for each pixel:
if pixel looks "quite white":
set pixel values to transparent
otherwise:
keep existing pixel values
and (assuming 8bit values) "quite white" would be:
where each r,g,b value is greater than "240"
AND each r,g,b value is within "20" of each other
This is the first time I've worked with raw pixel data in this way, and although works, it also performs extremely poorly. It seems like there must be a more efficient way of processing the data without iterating over each pixel in this manner? (Matrices?)
I was hoping someone with more experience in dealing with these things might be able to point out some of my more obvious mistakes/improvements in my algorithm.
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这仍然会访问每个像素,但可能会更快:
它避免了切片生成器,切片生成器将为每个像素复制整行像素(每次少一个像素)。
它还通过直接复制输入行来预分配输出行,然后只写入已更改的像素的 alpha 值。
更快的方法是根本不分配一组新的像素,而直接在源图像中的像素上写入(假设您不需要源图像进行其他任何操作)。
This still visits every pixel, but may be faster:
It avoids the slicen generator, which will be copying the entire row of pixels for every pixel (less one pixel each time).
It also pre-allocates the output row by directly copying the input row, and then only writes the alpha value of pixels which have changed.
Even faster would be to not allocate a new set of pixels at all, and just write directly over the pixels in the source image (assuming you don't need the source image for anything else).
老实说,我能想到的唯一启发是在图像上选择一些任意的随机点并使用 洪水填充。
仅当您的图像是大的连续白色部分时(如果您的图像是背景前面没有或只有小孔的对象,那么您很幸运 - 您实际上有一个启发式方法来从哪些点进行洪水填充) )。
(免责声明:我不是图像大师=/)
Honestly, the only heuristic I could conceive is picking a few arbitrary, random points on your image and using a flood fill.
This only works well if your image as large contiguous white portions (if your image is an object with no or little holes in front of a background, then you're in luck -- you actually have a heuristic for which points to flood fill from).
(disclaimer: I am no image guru =/ )
我很确定这没有捷径可走。你必须访问每一个像素。
I'm quite sure there is no short cut for this. You have to visit every single pixel.
这个问题似乎更多地与 Python 中的循环有关,而不是与图像有关。
Python 循环非常慢,最好避免它们并使用内置循环运算符。
在这里,如果您愿意复制图像,您可以使用列表理解:
The issue seems to have more to do with loops in Python than with images.
Python loops are extremely slow, it is best to avoid them and use built-ins loop operators instead.
Here, if you were willing to copy the image, you could use a list comprehension: