问题描述
这个错误 OSError: cannot write mode I;16 as JPEG
表示正在尝试保存一个 I;16
模式的图像(16位灰度图像),而 JPEG 格式只支持 8位的图像(比如 RGB
或 L
模式)。因此,无法直接将 I;16
模式的图像保存为 JPEG。
可行的解决方案
将保存的图片存为PNG格式而非JPEG格式。
理由:相比JPEG格式,PNG 格式支持更高位深的图像,可以直接保存 I;16
或其他类型的图像,而不会丢失原始数据。
# 保存图像为 PNG 格式
cropped_img.save(output_image_path, 'PNG')
注:原影像是一张进行了影像分割的I;16
模式的照片,不同颜色仅代表不同类别。
原影像(左) ,保存为PNG的影像(右)
尝试过的其他方案(失败案例)
1.I;16 模式转为RGB然后保存为JPEG
失败原因:保存的影像像元未能保持原有的值。I;16
模式的图像可以转换为 RGB
模式,但是要注意的是,I;16
模式是 16 位的灰度图像,每个像素值通常会在 0 到 65535 之间。而 RGB
模式是 8 位的,每个通道的像素值在 0 到 255 之间。因此,转换时需要对像素值进行适当的缩放。
通过简单的 convert('L')
和 convert('RGB')
,只会保持灰度值的视觉表现,而不会保留图像的原始数值,直接转换时会丢失一些信息(对 16 位的图像进行归一化处理,将其值缩放到 0-255
的范围内同理会丢失信息)。
# 如果图像是 I;16 模式,先转换为 L 模式,再转换为 RGB 模式
if img.mode == 'I;16':
img = img.convert('L') # 转换为 8 位灰度图
img = img.convert('RGB') # 转换为 RGB 模式
下图展示了上述方法存在的问题(原影像是一张进行了影像分割后的I;16
模式的照片,不同颜色仅代表不同类别)
原影像(左),转为RGB后保存的影像(右)
2. I;16 模式转为L模式然后保存为JPEG
保存的影像像元仍未能保持原有的值,原因同上。
# 如果图像是 I;16 模式,转换为 L 或 RGB 模式
if img.mode == 'I;16':
img = img.convert('L') # 转换为灰度图像(L 模式)
转为L模式的影像