7

我对 JPEG 进行了一些实验,文档说“100 完全禁用 JPEG 量化阶段”。

但是,我在保存过程中仍然进行了一些像素修改。这是我的代码:

import Image
red = [20,30,40,50,60,70];
img = Image.new("RGB", [1, len(red)], (255,255,255))
pix = img.load()

for x in range(0,len(red)):
    pix[0,x] = (red[x],255,255)

img.save('test.jpg',quality=100)

img = Image.open('test.jpg')
pix = img.load()

for x in range(0,len(red)):
    print pix[0,x][0],

我得到了意外的输出:22 25 42 45 62 65 我应该怎么做才能保留像素值?请注意,我还尝试使用imagejpeg使用 PHP ,当质量 = 100 时它给了我正确的值。

我可以png用来保存,但我想知道这背后的原因以及是否有任何选择可以避免

4

3 回答 3

4

JPEG 将始终存在有损风险,请参阅当质量设置为 100 时 Jpeg 是否无损?.

最好的选择是使用另一种格式,特别是如果您的实验是为了科学:) 即使您被迫从 JPEG 开始(这似乎不太可能),您也应该立即转换为无损格式以进行任何类型的分析和修改。

如果您真的想尝试使用 python 进行无损 JPEG 工作,您可以尝试jpegtran“来自 Independent Jpeg Group 的无损 jpeg 图像转换软件”,但正如 @Mark 所指出的,这不会让您走得太远。

顺便说一句,量化用于有损或无损压缩,所以我的猜测是

...100 完全禁用 JPEG 量化阶段。[1]

只是意味着它根本没有被压缩。

于 2013-03-18T15:56:26.850 回答
4

JPEG 由许多不同的步骤组成,其中许多会引入一些损失。通过使用仅包含红色的示例图像,您可能遇到了最严重的违规行为 -下采样或色度二次采样。一半的颜色信息被丢弃,因为眼睛对亮度变化比对颜色变化更敏感。

一些 JPEG 编码器可以配置为关闭子采样,包括 PIL 和 Pillow,通过设置subsampling=0. 无论如何,它不会给你一个完全无损的文件,因为还有其他步骤会引入损失。

于 2013-03-18T16:11:12.823 回答
1

相信我已经弄清楚如何保持当前的颜色二次采样和其他质量细节:

from PIL import Image, JpegImagePlugin as JIP

img = Image.open(filename)
img.save(
    filename + '2.jpg',                 # copy
    format='JPEG',
    exif=img.info['exif'],              # keep EXIF info
    optimize=True,
    qtables=img.quantization,           # keep quality
    subsampling=JIP.get_sampling(img),  # keep color res
)

根据https://www.exiv2.org/tags.html我发现 YCbCrSubSampling 标记未保存在 JPEG 文件的 EXIF 中:

在 JPEG 压缩数据中,使用 JPEG 标记代替此标记。

这一定是为什么在一个看似偏僻的地方有另一个功能可以抓住它。

于 2019-10-28T06:26:14.673 回答