【问题标题】:Is this possible to compress a JPEG file with zip libraries这可以用 zip 库压缩 JPEG 文件吗
【发布时间】:2012-02-05 06:32:03
【问题描述】:

据我所知,jpeg 文件在其他图像扩展名之间具有最佳压缩比,如果我更正,我们不能再压缩 jpeg 文件,因为它具有最佳压缩率,所以请帮助我。我创建了一些 jpeg 如下:

ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
ImageCodecInfo ici = null;
foreach(ImageCodecInfo codec in codecs) {
if(codec.MimeType == "image/jpeg")
    ici = codec;
}
EncoderParameters ep = new EncoderParameters();
ep.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, _quality);

using(MemoryStream ms = new MemoryStream()) {
     Bitmap capture = GetImage();
     capture.Save(ms, ici, ep);
  }

我用sharpziplib压缩它们,平均每个jpeg大小为130KB,压缩后每个文件压缩到大约70KB,这怎么可能?我能想象的只有 2 个答案。

1- 我们可以通过 zip 库以更高的压缩率压缩 Jpeg 文件

2- 我的 jpeg 文件未正确创建,我们可以创建更好的 jpeg(压缩比更高,因为我们无法使用 zip 库对其进行更多压缩)

有人知道吗?如果我们可以创建更好的 jpeg,请帮助我。

编辑:

这是我压缩 jpeg 的邮政编码:

void addnewentry(MemoryStream stream, string pass,
                 string ZipFilePath, string entryname){

ICSharpCode.SharpZipLib.Zip.ZipFile zf = new ZipFile(ZipFilePath);

            if(!String.IsNullOrEmpty(pass))
                zf.Password = pass;

            StaticDataSource sds = new StaticDataSource(Stream);
            zf.BeginUpdate();
            zf.Add(sds, entryName);
            zf.CommitUpdate();
            zf.IsStreamOwner = true;
            zf.Close();
}

public class StaticDataSource : IStaticDataSource {

    public Stream stream { get; set; }

    public StaticDataSource() {
        this.stream.Position = 0; 
    }

    public StaticDataSource(Stream stream) {

            this.stream = stream;
            this.stream.Position = 0;
        }

    public Stream GetSource() {
            this.stream.Position = 0;
            return stream;

    }

}

【问题讨论】:

  • 使用您选择的 ZIP 实用程序压缩 JPEG,它的大小将与原始 JPEG 大致相同(如果不大于)。 JPEG 文件已经被压缩(虽然没有使用 ZIP 压缩)。通过压缩 JPEG,您的收益将是微乎其微的。
  • JPEG 图像已被压缩。再次压缩它们不会有任何收获。
  • @CodyGray 那么我该如何压缩它们呢?如何创建无法压缩更多的 jpeg?
  • 它们已经被压缩了。你不需要压缩它们。如果您想要压缩程度更高的 JPEG,请在您用于保存 JPEG 的库中调高压缩级别设置。
  • @Saeid - 请记住,JPEG 是有损的,这意味着压缩得越多,结果的质量就越低。

标签: c# image compression zip jpeg


【解决方案1】:

正如大多数人已经说过的那样,您不能更轻松地压缩这些已经压缩的文件。有些人在 JPEG 重新压缩上努力工作(重新压缩 = 部分解码已经压缩的文件,然后使用自定义更强的模型和熵编码器压缩这些数据。重新压缩通常确保位相同的结果)。即使是先进的再压缩技术,我最多也只看到了 25% 的改进。 PackJPG 就是其中之一。你可以看看其他压缩器here。正如您所意识到的,即使是顶级压缩器也无法准确达到 25%(尽管它非常复杂)。

考虑到这些事实,ZIP(实际上是 deflate)并不能大幅提高压缩率(如果将它与前 10 名压缩器进行比较,它是一个非常陈旧且效率低下的压缩器)。我认为这个问题有两个可能的原因:

  1. 您不小心向 JPEG 流添加了一些额外数据(可能在 JPEG 流之后添加)。
  2. .NET 将大量冗余数据输出到 JFIF 文件。也许是一些大的 EXIF 数据等。

要解决此问题,您可以使用 JFIF 转储工具来观察 JFIF 容器内的内容。此外,您可能想用 PackJPG 尝试您的 JPEG 文件。

【讨论】:

  • 我也有相同的结果,通过打印屏幕按钮捕获屏幕并将 jpeg 保存在油漆中。你怎么解释这个?
  • 起初,我认为它们是一些渐变平滑的照片。但是,根据您的“证明”,我相信您正在压缩人工图像(例如计算机生成的图像、桌面屏幕截图、图表等)。如果是这样的话,难怪你可以进一步压缩它。因为,JPEG 为此类图像留下了相当多的熵。这可以通过简单的程序进一步减少。为了证明我的意思,只需使用 Paint 创建一个巨大的白色图像并将其保存为 JPEG。然后使用 ZIP 压缩器(尤其是 7-zip MAX 设置)压缩该文件。你会惊讶的:)
【解决方案2】:

没有人提到 JPEG 仅仅是一个容器这一事实。有许多压缩方法可用于该文件格式(JFIF、JPEG-2000、JPEG-LS 等)。进一步压缩该文件可能会产生不同的结果,具体取决于内容。 此外,一些相机存储了大量的 EXIF 数据(有时会产生大约 20K 的数据),这可能会导致您看到的差异。

【讨论】:

    【解决方案3】:

    JPEG 压缩算法有两个阶段:一个是“有损”阶段,即去除人眼无法察觉的视觉元素,另一个是“无损”阶段,使用一种称为 Huffmann 编码的技术压缩剩余数据。在 Huffmann 编码之后,进一步的无损压缩技术(如 ZIP)不会显着减小图像文件的大小。

    但是,如果您要将同一个小图像的多个副本压缩在一起,ZIP(“DEFLATE”)算法将识别数据的重复,并利用它来将总文件大小减少到小于单个文件的大小。这可能就是您在实验中看到的。

    简单地说,像霍夫曼编码(JPEG 的一部分)和 DEFLATE(在 ZIP 中使用)等无损压缩技术会尝试发现原始数据中的重复模式,然后使用更短的代码来表示这些重复模式。

    简而言之,您无法通过添加另一个无损压缩阶段来真正改善 JPEG。

    【讨论】:

    • 仅供参考,ZIP != LZW。 Zip 通常使用 deflate 而不是 LZW。
    • 根据你的回答我做了一个测试,一开始我压缩了一个jpeg文件,原始大小是99KB,压缩后大小是69KB(31%的比例),所以我压缩了15个jpeg文件类似(重复捕获屏幕)原始大小的平均值为 99KB,所有它们都以 31% 的比例压缩到平均 69KB,所以我认为还有另一种描述。
    • 有了这样的小文件,您很可能会看到@DanielS 在另一个答案中所描述的内容。 JPEG 容器允许您在压缩内容(EXIF 数据)之外存储有关图像的额外信息。根据用于创建图像的程序/相机以及图像本身的大小,它可能是相当大量的未压缩数据。如果不需要,您可以使用 EXIF 编辑工具或库从图像中删除此信息。如果您确实需要大量 EXIF 数据,那么将 JPEG 压缩在一起可能不是一个坏主意。
    【解决方案4】:

    您可以尝试使用 zlib 压缩任何内容。你只是并不总是会缩小尺寸。

    通常压缩整个 jpeg 文件会节省少量字节,因为它会压缩 jpeg header(包括任何纯文本 cmets 或 EXIF 数据)

    这可能无法完全解释您看到的 40K 压缩,除非您有大量的标头数据或您的 jpeg 数据以某种方式在内部包含大量重复值。

    【讨论】:

    • 但我觉得我的压缩文件不仅仅是header zip,130KB到70KB,你说这只是header压缩?
    【解决方案5】:

    压缩 JPEG 会减小大小,因为:EXIF 数据未压缩,JPEG 针对照片而不是类似 GIF 的数据进行了优化,压缩文件会创建单个数据流,从而允许跨多个文件和删除每个必须与磁盘上的特定块对齐的要求。后者可以单独为每个压缩文件节省大约 4KB。

    压缩预压缩图像的主要问题是它需要额外的工作(人力和 CPU)来准备和查看,这可能不值得付出努力(除非您有数百万张不常访问,或您正在开发的某种自动图像服务)。

    更好的方法是最小化本机文件大小,忘记 zip。有许多免费的库和应用程序可以帮助解决这个问题。例如,ImageOptim 将多个库合并为一个库(OptiPNG、PNGCrush、Zopfli、AdvPNG、Gifsicle、PNGOUT),以使用一系列激进的技巧来最小化大小。非常适合 PNG;还没有对 JPEG 进行太多尝试。

    尽管请记住,任何压缩都存在收益递减点。从长远来看,几个额外的字节是否真的很重要,由您决定。

    【讨论】:

      猜你喜欢
      • 2017-02-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多