为何Pillow的Image.getpixel会触发无法解包非可迭代int对象TypeError
报错原因
报错触发点在r,g,b = source.getpixel((w, h))行,本质是读取的download.png通道数和代码预期不匹配:
- 代码默认读取的是三通道RGB图,
getpixel()会返回长度为3的(r,g,b)元组,可以正常解包给三个变量 - 当图片是单通道灰度图、索引模式(P模式)图时,
getpixel()直接返回单个整数像素值,不是可迭代的元组,尝试解包为三个变量就会抛出TypeError: cannot unpack non-iterable int object - 如果图片是带透明层的RGBA四通道图,
getpixel()返回长度为4的元组,解包给三个变量也会触发长度不匹配的错误
修复方案
最通用的处理方式是在图片加载完成后,统一转换为代码预期的RGB模式,不需要单独判断原图的格式类型,修改后的代码如下:
from PIL import Image # 加载图片后统一转为三通道RGB格式,从根源解决通道数不匹配问题 source = Image.open("download.png").convert("RGB") width, height = source.size result = Image.new("RGBA", (width,height)) for w in range(width): for h in range(height): r,g,b = source.getpixel((w, h)) gray = int(r * 0.212 + g * 0.715 + b * 0.0746) result.putpixel((w, h), (gray, gray, gray, 255)) result.save("gray_house.png")
额外优化建议
- 如果你需要保留原图的透明通道逻辑,可以把转换方法改成
.convert("RGBA"),对应解包行改为r,g,b,a = source.getpixel((w, h))接收四个通道值即可 - 逐像素Python循环处理大尺寸图片效率极低,日常做灰度转换直接调用Pillow内置的
Image.convert("L")方法即可,内置为C层优化实现,处理速度比手写Python循环快数十倍。
内容的提问来源于stack exchange,提问作者animamoo
相关产品推荐
相关产品推荐

