合并字节数组转图像触发PIL.UnidentifiedImageError错误求解
问题根因
你的代码存在3个核心问题,直接触发图像无法识别的报错:
- 无意义的base64解码操作。从
buf.getvalue()拿到的是JPEG格式的原始二进制字节,并非base64编码的文本内容,直接对原始二进制调用base64.b64decode()会生成完全无意义的乱码,不可能被PIL识别为合法图像。 - 直接拼接两个独立JPEG的字节无法生成合法单图像文件。标准JPEG有固定结构:文件头 + 压缩数据 + 结束标记
0xFFD9,拼接后的数据包含两套文件头、两个结束标记,不符合任何单图像格式的规范,PIL无法解析这类非法字节流。 - 冗余导入:代码中引入的
email.mime.base、numpy.byte、array.array全程没有被调用,不影响运行但属于无效代码。
解决方案
根据你实际要实现的效果,对应方案如下:
场景1:将两张图合并为一张可直接查看的拼接大图
如果你的目标是做类似拼图的效果(左右/上下排布两张图),不需要手动操作字节,直接用PIL的画布接口实现即可,参考代码:
import io from PIL import Image # 读取并统一调整两张图的尺寸 compressedIm = Image.open(r"C:\Users\Student\Documents\Disso\Compressed_gabieureka.jpg") compressedIm_resize = compressedIm.resize((500, 500)) Im2 = Image.open(r"C:\Users\Student\Documents\Disso\Photos\votetemi.jpg") Im2_resize = Im2.resize((500, 500)) # 新建空白画布,此处为左右拼接的尺寸(宽1000高500),如果要上下拼接改为(500,1000)即可 merged_image = Image.new('RGB', (1000, 500)) # 依次将两张图贴到画布对应位置 merged_image.paste(compressedIm_resize, (0, 0)) merged_image.paste(Im2_resize, (500, 0)) # 展示、保存合并结果 merged_image.show() merged_image.save("TheirDate.png", "PNG")
场景2:拼接两个图像的字节流用于存储/传输,后续可拆分还原两张原图
如果你的目标是把两张图的二进制合并成一段数据方便传输,不能裸拼字节,需要额外记录单张图的字节长度作为边界标记,否则后续无法准确拆分两个文件,同时要删掉错误的base64解码步骤,参考代码:
import io import struct from PIL import Image # 生成两张图的JPEG二进制数据 compressedIm = Image.open(r"C:\Users\Student\Documents\Disso\Compressed_gabieureka.jpg") compressedIm_resize = compressedIm.resize((500, 500)) buf = io.BytesIO() compressedIm_resize.save(buf, format='JPEG') byte_compressedIm = buf.getvalue() Im2 = Image.open(r"C:\Users\Student\Documents\Disso\Photos\votetemi.jpg") Im2_resize = Im2.resize((500, 500)) buf2 = io.BytesIO() Im2_resize.save(buf2, format='JPEG') byte_Im2 = buf2.getvalue() # 拼接规则:先写入4字节的第一张图长度标记,再依次写入两张图的二进制内容 mergedBytearray = struct.pack('!I', len(byte_compressedIm)) + byte_compressedIm + byte_Im2 # 后续还原逻辑:先读取4字节长度标记,再按长度切分两段字节流即可 merge_buf = io.BytesIO(mergedBytearray) first_len = struct.unpack('!I', merge_buf.read(4))[0] first_img_bytes = merge_buf.read(first_len) second_img_bytes = merge_buf.read() # 验证拆分后的字节可以正常打开为图像 img1 = Image.open(io.BytesIO(first_img_bytes)) img2 = Image.open(io.BytesIO(second_img_bytes)) img1.show() img2.show()
内容的提问来源于stack exchange,提问作者Humza
相关产品推荐
相关产品推荐

