使用PIL库处理AWS S3下载图像时颜色失真,如何保留原图色彩?
如何保持从AWS S3下载后处理图像的原始颜色?
问题描述
我通过以下代码从AWS S3下载图像并处理,结果发现处理后的图像颜色发生了改变:
def capturing_image(img): res_img = [] try: res_img = Image.open(BytesIO(img)) res_img.verify() print("Valid Image") res_img = Image.open(BytesIO(img)) b, g, r = res_img.split() res_img = Image.merge('RGB', (r, g, b)) res_img = np.array(res_img) except Exception as ext: print("Invalid Image with Error: ",ext) return res_img S3ActualImage_file = getS3ActualImage(image_path) actual_image = capturing_image(S3ActualImage_file.content)
原始图像与处理后图像颜色不一致,请问如何保持图像的原始颜色?
解决方案
问题根源
颜色变色的核心原因是你错误地交换了RGB图像的红、蓝通道:
- 当使用PIL的
Image.open()打开标准RGB格式的图像(比如JPG、PNG这类常见格式)时,调用split()方法返回的通道顺序是红(R)、绿(G)、蓝(B)。 - 但你的代码里写了
b, g, r = res_img.split(),这相当于把红通道赋值给了变量b,蓝通道赋值给了变量r,完全搞反了通道顺序。 - 后续用
Image.merge('RGB', (r, g, b))合并时,就把原本的蓝通道当成红通道,红通道当成蓝通道,自然会导致颜色严重失真。
修改后的代码
只需要移除错误的通道交换步骤,就能保留原始颜色:
def capturing_image(img): res_img = [] try: res_img = Image.open(BytesIO(img)) res_img.verify() print("Valid Image") # 重新打开图像(因为verify()会将文件指针移到末尾,需要重新读取) res_img = Image.open(BytesIO(img)) # 直接转换为numpy数组,保留原始RGB通道顺序 res_img = np.array(res_img) except Exception as ext: print("Invalid Image with Error: ", ext) return res_img
特殊场景处理
如果你的业务中确实存在需要处理BGR格式图像的情况(比如某些特定格式的图片,或者来自OpenCV处理过的图像),可以先添加判断逻辑,再选择性地交换通道:
def capturing_image(img): res_img = [] try: res_img = Image.open(BytesIO(img)) res_img.verify() print("Valid Image") res_img = Image.open(BytesIO(img)) # 这里可以根据图像来源、格式等添加判断条件 is_bgr_format = False # 替换为你的实际判断逻辑 if is_bgr_format: b, g, r = res_img.split() res_img = Image.merge('RGB', (r, g, b)) res_img = np.array(res_img) except Exception as ext: print("Invalid Image with Error: ", ext) return res_img
内容的提问来源于stack exchange,提问作者ebsavvy
相关产品推荐
相关产品推荐

