简体   繁体   English

PIL jpeg,如何保留像素颜色

[英]PIL jpeg, how to preserve the pixel color

I have some experiments with JPEG, the doc said "100 completely disables the JPEG quantization stage."我对 JPEG 进行了一些实验,文档说“100 完全禁用 JPEG 量化阶段”。

However, I still got some pixel modification during saving.但是,我在保存过程中仍然进行了一些像素修改。 Here is my code:这是我的代码:

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],

I got unexpected output: 22 25 42 45 62 65 What should I do to preserve the pixel value ?我得到了意外的输出: 22 25 42 45 62 65我应该怎么做才能保留像素值? Please note that I also tried with PHP using imagejpeg and It gives me the correct value when quality=100.请注意,我还尝试使用imagejpeg使用 PHP,当质量 = 100 时它给了我正确的值。

I can use png to preserve, but I want to know the reason behind this and if there is any option to avoid我可以使用png来保存,但我想知道这背后的原因以及是否有任何选择可以避免

JPEG will always carry risk of lossyness, see Is Jpeg lossless when quality is set to 100? JPEG 将始终存在有损风险,请参阅当质量设置为 100 时 Jpeg 是否无损? . .

Your best bet is to use another format, especially if your experiments are for science :) Even if you're forced to start with JPEG (which seems unlikely) you should immediately convert to a lossless format for any kind of analysis and modification.最好的选择是使用另一种格式,特别是如果您的实验是为了科学:) 即使您被迫从 JPEG 开始(这似乎不太可能),您也应该立即转换为无损格式以进行任何类型的分析和修改。

If you really want to try lossless JPEG work with python you can try jpegtran , "the lossless jpeg image transformation software from the Independent Jpeg Group" , but as @Mark notes, this won't get you very far.如果您真的想尝试使用 python 进行无损 JPEG 工作,您可以尝试jpegtran ,“来自 Independent Jpeg Group 的无损 jpeg 图像转换软件” ,但正如 @Mark 所指出的,这不会让您走得太远。

By the way, quantization is used in lossy or lossless compression alike, so my guess is that顺便说一句,量化用于有损或无损压缩,所以我的猜测是

...100 completely disables the JPEG quantization stage. ...100 完全禁用 JPEG 量化阶段。 [1] [1]

simply means that it's not compressed at all.只是意味着它根本没有被压缩。

JPEG consists of many different steps, many of which introduce some loss. JPEG 由许多不同的步骤组成,其中许多会引入一些损失。 By using a sample image containing only red, you've probably run across the worst offender - downsampling or chroma subsampling .通过使用仅包含红色的示例图像,您可能遇到了最严重的违规行为 -下采样或色度二次采样 Half of the color information is thrown away because the eye is more sensitive to brightness changes than color changes.一半的颜色信息被丢弃,因为眼睛对亮度变化比对颜色变化更敏感。

Some JPEG encoders can be configured to turn off subsampling, including PIL and Pillow by setting subsampling=0 .一些 JPEG 编码器可以通过设置subsampling=0配置为关闭子采样,包括 PIL 和 Pillow。 In any case it won't give you a completely lossless file since there are still other steps that introduce a loss.无论如何,它不会给你一个完全无损的文件,因为还有其他步骤会引入损失。

Believe I've figured out how to keep the current color subsampling and other quality details:相信我已经弄清楚如何保持当前的颜色二次采样和其他质量细节:

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
)

Per https://www.exiv2.org/tags.html I've found that the YCbCrSubSampling tag is not kept in EXIF in JPEG files:根据https://www.exiv2.org/tags.html我发现 YCbCrSubSampling 标记未保存在 JPEG 文件的 EXIF 中:

In JPEG compressed data a JPEG marker is used instead of this tag.在 JPEG 压缩数据中,使用 JPEG 标记代替此标记。

This must be why there is another function in a seemingly out of the way place to to grab it.这一定是为什么在一个看似偏僻的地方有另一个功能可以抓住它。

(Believe I found it here: https://newbedev.com/determining-jpg-quality-in-python-pil ) (相信我在这里找到它: https ://newbedev.com/determining-jpg-quality-in-python-pil)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM