首页 > 解决方案 > 将灰度 JPEG 转换为 rgb JPEG,保留质量

问题描述

我有一些包含灰度图像的 JPEG 文件。我希望将这些图像转换为 RGB(即三个通道)并将它们保存为新的 JPEG 文件,并具有与原始图像相同(或几乎相同)的质量。我希望使用 Python Pillow 包。

我尝试了以下步骤,但它没有保留原始图像的质量:

$ jhead gray.JPEG
File name    : gray.JPEG
File size    : 68741 bytes
File date    : 2021:10:25 04:54:30
Resolution   : 500 x 333
Color/bw     : Black and white
JPEG Quality : 96
gray = PIL.Image.open("gray.JPEG")
rgb = gray.convert(mode="RGB")
rgb.save("rgb.JPEG")
$ jhead rgb.JPEG
File name    : rgb.JPEG
File size    : 25622 bytes
File date    : 2021:10:25 05:04:20
Resolution   : 500 x 333
JPEG Quality : 75

如何使用 PIL.Image 进行转换并保持 JPEG 图像的质量?

标签: python-imaging-library

解决方案


更新的答案

假设您专注于完成工作,而不是像下面这样专门基于 PIL/Pillow 的答案,您可以使用ImageMagick做您想做的事情,而无需在终端中编写任何代码,如下所示。首先复制文件并在单独的目录中工作,这mogrify是一个非常强大的命令:

magick mogrify -colorspace srgb -type truecolor *.jpg

如果要避免覆盖原始文件,请指定输出文件的路径:

mkdir OUTPUT
magick mogrify -path OUTPUT -colorspace srgb -type truecolor *.jpg

这也应该保留 dpi、质量和其他元数据。如果您喜欢这些结果但真的坚持使用 Python,我很确定您可以使用派生自ImageMagick的wand在 Python 中完成上述操作。

原始答案

这似乎是一些讨论和混淆的话题。基本上,质量实际上并不直接嵌入 JPEG 中。我认为目前最安全的选择是提取原件的质量并使用相同的值进行编写,如下所示:

import subprocess
from PIL import Image

# Load input image and convert to RGB
filename = 'input.jpg'
im = Image.open(filename).convert('RGB')

# Get quality estimate of original using "exiftool"
proc = subprocess.run(["exiftool","-s3","-JPEGQualityEstimate",filename], capture_output=True)
q=int(proc.stdout)
print(f'File: {filename}, estimated quality: {q}')

# Save with that quality
im.save('result.jpg', quality=q)

对于生产质量,您应该检查结果并处理错误/异常等。


如果你还没有exiftool安装,你可以使用这个命令和ImageMagick来提取质量:

magick input.jpg -format %Q info:

如果你想坚持jhead,你可以使用类似的东西:

import re

# Guesstimate quality using "jhead"
proc = subprocess.run(["jhead",filename], capture_output=True)
it = re.search(r'JPEG Quality\s*:\s*(\d+)', str(proc.stdout))
q = int(it.group(1))

推荐阅读