gpt4 book ai didi

python - C# 和 Python 中的 JPEG 压缩差异

转载 作者:行者123 更新时间:2023-12-04 11:56:27 25 4
gpt4 key购买 nike

我正在将一些图像处理功能从 .NET 转移到 Python,限制条件是输出图像必须以与在 .NET 中完全相同的方式进行压缩。但是,当我比较 .jpg 时在类似 text-compare 的工具上输出文件并选择 Ignore nothing ,文件的压缩方式存在显着差异。
例如:
python

bmp = PIL.Image.open('marbles.bmp')

bmp.save(
'output_python.jpg',
format='jpeg',
dpi=(300,300),
subsampling=2,
quality=75
)
.NET
ImageCodecInfo jgpEncoder = ImageCodecInfo.GetImageDecoders().First(codec => codec.FormatID == ImageFormat.Jpeg.Guid);
EncoderParameters myEncoderParameters = new EncoderParameters(1);
myEncoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, 75L);

Bitmap bmp = new Bitmap(directory + "marbles.bmp");

bmp.Save(directory + "output_net.jpg", jgpEncoder, myEncoderParameters);
exiftool output_python.jpg -a -G1 -w txt
[ExifTool]      ExifTool Version Number         : 12.31
[System] File Name : output_python.jpg
[System] Directory : .
[System] File Size : 148 KiB
[System] File Modification Date/Time : 2021:09:28 09:19:20-06:00
[System] File Access Date/Time : 2021:09:28 09:19:21-06:00
[System] File Creation Date/Time : 2021:09:27 21:33:35-06:00
[System] File Permissions : -rw-rw-rw-
[File] File Type : JPEG
[File] File Type Extension : jpg
[File] MIME Type : image/jpeg
[File] Image Width : 1419
[File] Image Height : 1001
[File] Encoding Process : Baseline DCT, Huffman coding
[File] Bits Per Sample : 8
[File] Color Components : 3
[File] Y Cb Cr Sub Sampling : YCbCr4:2:0 (2 2)
[JFIF] JFIF Version : 1.01
[JFIF] Resolution Unit : inches
[JFIF] X Resolution : 300
[JFIF] Y Resolution : 300
[Composite] Image Size : 1419x1001
[Composite] Megapixels : 1.4
exiftool output_net.jpg -a -G1 -w txt
[ExifTool]      ExifTool Version Number         : 12.31
[System] File Name : output_net.jpg
[System] Directory : .
[System] File Size : 147 KiB
[System] File Modification Date/Time : 2021:09:28 09:18:05-06:00
[System] File Access Date/Time : 2021:09:28 09:18:52-06:00
[System] File Creation Date/Time : 2021:09:27 21:32:19-06:00
[System] File Permissions : -rw-rw-rw-
[File] File Type : JPEG
[File] File Type Extension : jpg
[File] MIME Type : image/jpeg
[File] Image Width : 1419
[File] Image Height : 1001
[File] Encoding Process : Baseline DCT, Huffman coding
[File] Bits Per Sample : 8
[File] Color Components : 3
[File] Y Cb Cr Sub Sampling : YCbCr4:2:0 (2 2)
[JFIF] JFIF Version : 1.01
[JFIF] Resolution Unit : inches
[JFIF] X Resolution : 300
[JFIF] Y Resolution : 300
[Composite] Image Size : 1419x1001
[Composite] Megapixels : 1.4
marbles.bmp sample image
文本比较差异
Difference on text-compare
Marbles difference details
问题
  • 假设这两种 JPEG 压缩实现可以产生相同的输出文件是否合理?
  • 如果是这样,要么是 PILSystem.Drawing.Image做任何额外的步骤,比如抗锯齿,使结果不同?
  • 或者 PIL 是否有其他参数.save()让它表现得更像 C# 中的 JPEG 编码器?

  • 谢谢
    更新
    基于 Jeremy's recommendation , 我用了 JPEGsnoop比较文件之间的更多细节,发现亮度和色度表是不同的。我修改了代码:
    bmp = PIL.Image.open('marbles.bmp')

    output_net = PIL.Image.open('output_net.jpg')

    bmp.save(
    'output_python.jpg',
    format='jpeg',
    dpi=(300,300),
    subsampling=2,
    qtables=output_net.quantization,
    #quality=75
    )
    现在表是相同的,但文件之间的差异没有改变。 JPEGsnoop 现在显示的唯一区别在于 Compression statsHuffman code histogram stats . output_net.jpeg
    *** Decoding SCAN Data ***
    OFFSET: 0x0000026F
    Scan Decode Mode: Full IDCT (AC + DC)

    Scan Data encountered marker 0xFFD9 @ 0x00024BE7.0

    Compression stats:
    Compression Ratio: 28.43:1
    Bits per pixel: 0.84:1

    Huffman code histogram stats:
    Huffman Table: (Dest ID: 0, Class: DC)
    # codes of length 01 bits: 0 ( 0%)
    # codes of length 02 bits: 1664 ( 7%)
    # codes of length 03 bits: 18238 ( 81%)
    # codes of length 04 bits: 1807 ( 8%)
    # codes of length 05 bits: 715 ( 3%)
    # codes of length 06 bits: 4 ( 0%)
    # codes of length 07 bits: 0 ( 0%)
    ...
    output_python.jpg
    *** Decoding SCAN Data ***
    OFFSET: 0x0000026F
    Scan Decode Mode: Full IDCT (AC + DC)

    Scan Data encountered marker 0xFFD9 @ 0x00025158.0

    Compression stats:
    Compression Ratio: 28.17:1
    Bits per pixel: 0.85:1

    Huffman code histogram stats:
    Huffman Table: (Dest ID: 0, Class: DC)
    # codes of length 01 bits: 0 ( 0%)
    # codes of length 02 bits: 1659 ( 7%)
    # codes of length 03 bits: 18247 ( 81%)
    # codes of length 04 bits: 1807 ( 8%)
    # codes of length 05 bits: 711 ( 3%)
    # codes of length 06 bits: 4 ( 0%)
    # codes of length 07 bits: 0 ( 0%)
    ...
    我现在正在寻找一种通过 PIL 同步这些值的方法。 .

    最佳答案

    Is it reasonable to assume that these two implementations of JPEG compression could yield identical output files?


    答案并非如此。
    JPEG 压缩的要点是有损失的高压缩。即使质量设置为 100,损失也是不可避免的,因为该算法需要无限精度来精确复制源图像。
    如果使用相同的参数对两种算法进行相同的编码:精度、边界选择和填充/偏移规范以提供 FFT 的 2 次幂大小,则可以生成相同的文件。
    JPEG 算法的实现可以使用预传递来优化算法的参数。
    鉴于两种实现的参数优化不同,输出不太可能相同。

    Are there additional parameters to PIL .save() to make it behave more like the JPEG encoder in C#?


    我不能直接回答这个问题,但是,你可以使用这个包: Python for.NET从 Python 访问 C# JPEG 编码器。该解决方案将提供一致的相同结果。

    为什么除了教育值(value)之外,还有人需要二进制兼容性吗?
    在我认为解决这个问题的所有实际场景中,唯一的需要是保存图像的附加散列:将新散列保存在单独的字段中。
    选择一种技术并使用它,直到它不再适合您的需要/要求。
    如果没有(最好是之前),找到垫片来填补空白并重写代码以利用新技术。

    关于python - C# 和 Python 中的 JPEG 压缩差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69365037/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com