使用PIL将JPEG转PNG后颜色异常的技术求助
JPG转PNG颜色失真问题排查与解决建议
我在Lambda函数中使用Python PIL库将图片转为PNG格式,近期遇到部分JPG转PNG后颜色明显变化的问题。已尝试过转为RGB而非RGBA、关闭PNG保存时的optimize参数、保留颜色配置文件,但均未解决问题。
转换代码
def convert_image(s3_source_key, prefix): playout_key = prefix + '_playout.png' thumbnail_key = prefix + '_thumb.png' all_good = False try: s3_client = boto3.client('s3') # 读取原始文件 file_object = s3_client.get_object(Bucket=S3_SOURCE_BUCKET, Key=s3_source_key)['Body'] file_buffer = file_object.read() im_orig = Image.open(BytesIO(file_buffer)) # 保存为PNG(即使原文件已是PNG) buffer = BytesIO() im_orig.convert('RGBA').save(buffer, 'PNG', optimize=True) buffer.seek(0) s3_client.put_object(Body=buffer, Bucket=BUCKET_NAME, Key=playout_key) # 创建缩略图 im = Image.open(BytesIO(file_buffer)) width, height = im.size new_w = width / 3 # 默认缩放系数为3 new_h = height / 3 im = im.convert("RGBA") im = im.resize((int(new_w), int(new_h))) buffer = BytesIO() im.save(buffer, 'PNG') buffer.seek(0) s3_client.put_object(Body=buffer, Bucket=BUCKET_NAME, Key=thumbnail_key)
解决建议
- 处理CMYK色彩空间的JPG:部分JPG采用CMYK模式,PIL直接
convert转换会导致颜色失真。建议通过ICC配置文件做专业色域转换:from PIL import ImageCms from io import BytesIO # 读取图片及ICC配置 im_orig = Image.open(BytesIO(file_buffer)) icc_profile = im_orig.info.get('icc_profile') # CMYK转RGB(基于ICC配置) if im_orig.mode == 'CMYK' and icc_profile: cmyk_profile = ImageCms.ImageCmsProfile(BytesIO(icc_profile)) srgb_profile = ImageCms.createProfile("sRGB") im_processed = ImageCms.profileToProfile(im_orig, cmyk_profile, srgb_profile) else: im_processed = im_orig.convert('RGB') # 保存PNG时嵌入ICC配置 buffer = BytesIO() im_processed.save(buffer, 'PNG', icc_profile=icc_profile) - 复用图片对象:代码中两次调用
Image.open(BytesIO(file_buffer)),可改为读取一次后复用,减少重复处理可能带来的问题 - 升级Pillow版本:Lambda环境中的旧版Pillow可能存在色彩处理bug,升级到最新稳定版(如9.x以上)
- 保留图片元数据:部分JPG带有特殊的色彩校正信息,可尝试在保存时保留EXIF元数据,比如添加
exif=im_orig.info.get('exif')参数
内容的提问来源于stack exchange,提问作者Alex Oat
相关产品推荐
相关产品推荐

