如何检测我的图像是否被截断并安全地加载它?

How to detect if my image is truncated and load it thread-safely?

我有一个图像处理功能,可以制作图像的缩略图并获取其宽度和高度。我设置 LOAD_TRUNCATED_IMAGE = True 以加载截断的图像。

    from PIL import Image, ImageFile

    ImageFile.LOAD_TRUNCATED_IMAGES = True
    try:
        image = Image.open(buffer)
        image = image.convert('RGB')
        ...

    finally:
        ImageFile.LOAD_TRUNCATED_IMAGES = False

但是因为它在多线程上工作,所以全局变量 (LOAD_TRUNCATED_IMAGE) 似乎不是线程安全的,有时无法加载截断的图像并引发 OSError。

我想做的是

  1. 安全加载截断的图像线程。
  2. 引发 OSError 以提醒图像被截断。

有什么办法可以解决这些问题吗?

看了相关的PIL github issue,发现只有try-catch的方法。所以如果我能找到另一种方法来检测有或没有 PIL 的图像截断,那就太好了。

你没有提到图片的类型:

  • 如果是JPEG,则必须以EOI结尾,即两个字节0xff 0xd9
  • 如果它们是 PNG,它们必须以 IEND 标记结尾 49 45 4e 44 ae 42 60 82

我无法靠近计算机进行测试,但这应该显示 BytesIO 中 JPEG 的最后 2 个字节是 ff d9

from PIL import Image
from io import BytesIO

# Create black image
im = Image.new("RGB",(64,48))

# Put into a BytesIO
bytes = BytesIO()
im.save(bytes, format="JPEG")

# Check last 2 bytes
buff = bytes.getbuffer()
print(buff[-2:].hex())

PNG也是如此:

from PIL import Image
from io import BytesIO

im = Image.new("RGB",(64,48))

bytes = BytesIO()
im.save(bytes, format="PNG")
buff = bytes.getbuffer()
print(buff[-8:].hex())