我有一些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
保留,但我想知道背后的原因以及是否有任何选项可以避免
答案 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标记 而不是此标签。
这一定是为什么在看似遥不可及的地方要抓取它的另一个功能。