PIL jpeg,如何保留像素颜色

时间:2013-03-18 15:49:29

标签: python image image-processing python-imaging-library

我有一些JPEG实验,the doc说“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保留,但我想知道背后的原因以及是否有任何选项可以避免

3 个答案:

答案 0 :(得分:2)

JPEG由许多不同的步骤组成,其中许多步骤引入了一些损失。通过使用仅包含红色的样本图像,您可能遇到了最严重的罪犯 - downsampling or chroma subsampling。一半的颜色信息被丢弃,因为眼睛对亮度变化比颜色变化更敏感。

可以通过设置subsampling=0将某些JPEG编码器配置为关闭子采样,包括PIL和Pillow。在任何情况下,它都不会给你一个完全无损的文件,因为还有其他步骤会导致丢失。

答案 1 :(得分:1)

JPEG始终存在有损风险,请参阅Is Jpeg lossless when quality is set to 100?

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

如果你真的想尝试使用python进行无损JPEG工作,你可以试试jpegtran, "the lossless jpeg image transformation software from the Independent Jpeg Group",但正如@Mark所说,这不会让你走得太远。

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

  

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

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

答案 2 :(得分:0)

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

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标记   而不是此标签。

这一定是为什么在看似遥不可及的地方要抓取它的另一个功能。