Можно ли сжимать файл JPEG с помощью zip-библиотек? - PullRequest
4 голосов
/ 08 января 2012

Как я знаю, файл jpeg имеет лучшую степень сжатия между другими расширениями изображений, и если я исправлю, мы не сможем больше сжимать файл jpeg, потому что он имеет лучшее сжатие, поэтому, пожалуйста, помогите мне в этом.Я создаю несколько jpegs следующим образом:

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 составляет 130 КБ, а после сжатия каждого файла, сжатого до 70 КБ, как это возможно?есть только 2 ответа, которые я могу себе представить.

1- Мы можем сжать файл JPEG с большей степенью сжатия с помощью библиотек zip

2 - Мой файл JPEG создан неправильно, и мы можем создать лучшие файлы JPEG(с большей степенью сжатия, поскольку мы не можем больше сжимать их с помощью zip-библиотек)

Кто-нибудь знает об этом?если мы сможем создать лучшие jpegs, пожалуйста, помогите мне в этом.

Редактировать:

это мой почтовый индекс для сжатия jpegs:

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;

    }

}

Ответы [ 5 ]

3 голосов
/ 08 января 2012

Как уже указывало большинство людей, вы не сможете легко сжать такие уже сжатые файлы.Некоторые люди усердно работают над повторным сжатием JPEG (пересжатие = частичное декодирование уже сжатого файла, а затем сжатие этих данных с помощью более надежной модели и энтропийного кодера. Повторное сжатие обычно обеспечивает битовые идентичные результаты).Даже при использовании этих передовых методов рекомпрессии я видел улучшение только на 25%. PackJPG является одним из них.Вы можете посмотреть другие компрессоры здесь .Как вы понимаете, даже компрессор высшего ранга не может достичь ровно 25% (даже если он очень сложный).

Принимая во внимание эти факты, ZIP (на самом деле выкачанный) не может значительно улучшить сжатие (это очень старая версия).и неэффективно, если сравнить его с топ-10 компрессорами).Я полагаю, что есть две возможные причины этой проблемы:

  1. Вы случайно добавляете некоторые дополнительные данные в поток JPEG (возможно, добавляя после потока JPEG).
  2. .NET выводит многоизбыточные данные в файл JFIF.Может быть, некоторые большие данные EXIF ​​и тому подобное.

Чтобы решить эту проблему, вы можете использовать инструмент дампа JFIF, чтобы посмотреть, что находится внутри контейнера JFIF.Кроме того, вы можете попробовать свои файлы JPEG с PackJPG.

2 голосов
/ 08 января 2012

Алгоритм сжатия JPEG состоит из двух этапов: этап «с потерями», когда удаляются визуальные элементы, которые должны быть незаметны для человеческого глаза, и этап «без потерь», когда остальные данные сжимаются с использованием метода, называемого кодированием Хаффмана. После кодирования Хаффмана дальнейшие методы сжатия без потерь (например, ZIP) не уменьшат размер файла изображения в значительном размере.

Однако, если вам нужно было сжать несколько копий одного и того же небольшого изображения вместе, алгоритм ZIP («УДАЛИТЬ») распознает повторение данных и использует его, чтобы уменьшить общий размер файла до величины, меньшей суммы размер отдельных файлов. Это может быть тем, что вы видите в своем эксперименте.

Проще говоря, методы сжатия без потерь, такие как кодирование Хаффмана (часть JPEG) и DEFLATE (используется в ZIP), пытаются обнаружить повторяющиеся шаблоны в ваших исходных данных, а затем представить эти повторяющиеся шаблоны с использованием более коротких кодов.

Короче говоря, вы не сможете реально улучшить JPEG, добавив еще один этап сжатия без потерь.

2 голосов
/ 08 января 2012

Никто не упомянул тот факт, что JPEG - это просто контейнер. Существует много методов сжатия, которые можно использовать с этим форматом файла (JFIF, JPEG-2000, JPEG-LS и т. Д.). Дальнейшее сжатие этого файла может привести к различным результатам в зависимости от содержимого. Кроме того, некоторые камеры хранят огромные объемы данных EXIF ​​(иногда это приводит к 20КБ данных), и это может объяснить разницу, которую вы видите.

1 голос
/ 08 января 2012

Вы можете попытаться сжимать что-либо с помощью zlib. Вы просто не всегда получаете уменьшение в размере.

Обычно сжатие всего файла jpeg приводит к экономии нескольких байтов, так как сжимает заголовок jpeg (включая любые комментарии в виде простого текста или EXIF ​​ данные)

Это может не полностью учитывать 40K сжатия, которое вы видите, если только у вас нет огромного количества данных заголовка или ваши данные jpeg каким-то образом заканчиваются множеством повторяющихся значений внутри.

0 голосов
/ 21 августа 2017

Сжатие JPEG-файлов уменьшает размер, потому что : данные EXIF ​​не сжимаются, JPEG оптимизирован для фотографий, а не GIF-подобных данных, а сжатие файлов создает единый поток данных, позволяя использовать шаблоны для нескольких файлов и удалятьтребование, чтобы каждый из них был выровнен с определенным блоком на диске.Последний может в одиночку сэкономить около 4 КБ на сжатый файл.

Основная проблема с сжатием предварительно сжатых изображений заключается в том, что для подготовки и просмотра требуется дополнительная работа (человек и процессор), что можетне стоит затраченных усилий (если у вас нет миллионов изображений, к которым редко обращаются, или вы разрабатываете какой-то автоматизированный сервис изображений).

Лучший подход - минимизировать собственный размер файла , забыв зип.Есть много бесплатных библиотек и приложений, чтобы помочь с этим.Например, ImageOptim объединяет несколько библиотек в одну (OptiPNG, PNGCrush, Zopfli, AdvPNG, Gifsicle, PNGOUT) для создания множества агрессивных трюков для минимизации размера.Отлично работает для PNG;Я не слишком много пробовал с JPEG.

Хотя помните, что при любом сжатии всегда есть точка уменьшения отдачи.Вам решать, действительно ли в конечном итоге имеет значение несколько дополнительных байтов.

...