关于 plt.imread/PIL.Image.open 导致 ValueError: source code string cannot contain null bytes 的解决方案

一个困扰了很久的小问题,今晚终于想通了一点,希望能帮到有相同困惑的朋友。

问题

import matplotlib.pyplot as plt
from PIL import Image

my_image = 'xxx.jpg'

# 下面两种情况都可能会导致 ValueError: source code string cannot contain null bytes
# 而出错的问题很让人抓狂,是在源码文件 ImagePalette.py 中的
# “from . import ImageColor, GimpPaletteFile, GimpGradientFile, PaletteFile” 代码行
image1 = plt.imread(my_image)
image2 = Image.open(my_image)

解决方案一

不要使用 PNG 格式以外的图片!不要使用 PNG 格式以外的图片!不要使用 PNG 格式以外的图片!

如下面这个情况就稳得多

import matplotlib.pyplot as plt
from PIL import Image

# 唯一的不同是换为了 PNG 格式的图片
my_image = 'xxx.png'

# 下面两种情况都可能会导致 ValueError: source code string cannot contain null bytes
image1 = plt.imread(my_image)
image2 = Image.open(my_image)

出错原因补充:通过查看 plt.imread 的源码不难发现,plt 只完成了对 PNG 格式图片的处理,其他格式事实上还是通过调用 PIL.Image 来处理的。而这种情况下,如果你恰好使用的是 anaconda3,或恰好使用的是 5.x.x 的 PIL (在 python 3 里面其实叫 Pillow) 而不是更新版本的比如 6.x/7.x,那么就有可能会遇上这问题。放心,这不是你的锅,是代码本身的问题……虽然笔者也看不懂是代码编写本身的 bug 还是兼容性的问题。总之,由此有了本文的第二个解决方案:

解决方案二

在 cmd (以管理员身份运行) 中运行命令 “pip install --upgrade pillow” 升级 PIL (比如升级为 6.0.0,反正我这样做之后错误就消失了)。从根本上解决问题。

结语

万万没想到,纠结了那么多年的一个 bug,竟然是代码版本的问题。

你可能感兴趣的:(复盘)