387 字
2 分钟
忽略 python 中 libpng 的 iCCP 警告
问题描述
在使用 Python 处理 PNG 图片时,经常会遇到以下警告:
libpng warning: iCCP: known incorrect sRGB profile
根据 libpng 官方的说法, 图片本来就是坏的, 但是 libpng 仍然会尝试去处理它, 导致这个警告.
但即使项目中没有用任何 png 图片素材, 仅仅用 Tkinter 创建一个窗口都会触发一大堆这个警告刷屏, 强迫症患者震怒.

而且这个错误是直接调用 c 函数输出的, 十分恶心.
尝试过程
网上看了一堆垃圾教程, 没一个有用的. 总结一下这些垃圾教程教的方法:
- 使用 warning 库屏蔽输出. 不可能有用, warning 库只能做到 python 层面屏蔽, 输出都不经过 python.
- 重定向 stderr. python 内置的 sys.stderr 本质还是经过 python 包装过的, 无法重定向 c 的输出.
解决方法
还是重定向 stderr 输出管道, 并不优雅, 但至少没有一堆警告刷屏了.
与直接用sts.stderr = open(os.devnull, 'w') 不同, 这里需要更底层的操作.
这里实现一个上下文管理器, 在进入时重定向 stderr, 离开时恢复原状.
class LibpngFilter: def __enter__(self): self.pipe_in, pipe_out = os.pipe() self.orig_fd = os.dup(2) os.dup2(pipe_out, 2) os.close(pipe_out) self.stop = False
def reader(): f = os.fdopen(self.pipe_in) for line in f: if self.stop: break if line.startswith("libpng warning:"): # 屏蔽逻辑, 可以根据需要修改 break sys.__stderr__.write(line) sys.__stderr__.flush() f.close()
self.thread = threading.Thread(target=reader, daemon=True) self.thread.start() return self
def __exit__(self, type, val, tb): self.stop = True os.dup2(self.orig_fd, 2) os.close(self.orig_fd) self.thread.join()使用方法
with LibpngFilter(): ... # 处理 png 图片的代码 忽略 python 中 libpng 的 iCCP 警告
https://blog.xiyang6666.top/posts/fragmented-issues/2025-6-1_忽略-python-中-libpng-的-iccp-警告/