Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is this possible to compress a JPEG file with zip libraries

As I know the jpeg file have a best compression ratio between another image extensions, and if I correct we can not more compress a jpeg file because that have best compression, so please help me about this. I create some jpegs as following:

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);
  }

And I zipped them with sharpziplib, in average every jpeg size is 130KB and after zip every file compressed to about 70KB, how it possible? there is just 2 answer I can Imagine.

1- We can Compress Jpeg file with more compression ratio by zip libraries

2- My jpeg file not correctly created, and we can create better jpegs (with more compression ratio as we can not more compress them with zip libraries)

Does any one know about this? if we can create better jpegs please help me about it.

Edit:

this is my zip code to compress 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;

    }

}
like image 580
Saeid Avatar asked Feb 22 '23 22:02

Saeid


2 Answers

As most of people already stated, you can't compress such already compressed files further easily. Some people works hard on JPEG recompression (recompression = partially decoding already compressed file, and then compressing those data with a custom stronger model and entropy coder. Recompression usually ensures bit-identical results). Even that advanced recompression techniques, I only saw at most 25% improvement. PackJPG is one them. You can have a look at the other compressors here. As you realize, even top rank compressor couldn't reach exactly 25% (even though it's very complex).

Taking these facts into considerations, ZIP (actually deflate) cannot improve compression that much (it's a very old and inefficient if you compare it with top 10 compressors). I believe there are two possible reasons for that problem:

  1. You're accidentally adding some extra data to JPEG stream (possibly adding after JPEG stream).
  2. .NET outputs lots of redundant data to JFIF file. Maybe some big EXIF data and such.

To solve the problem, you can use a JFIF dump tool to observe what's inside the JFIF container. Also, you may want to try your JPEG files with PackJPG.

like image 51
Osman Turan Avatar answered Mar 06 '23 20:03

Osman Turan


No one has mentioned that fact that JPEG is merely a container. There are many compression methods that can be used with that file format (JFIF, JPEG-2000, JPEG-LS, etc.) Further compressing that file can yield varying results depending on the content. Also, some cameras store huge amounts of EXIF data (sometimes resulting in about 20K of data) and that might account for the difference you're seeing.

like image 25
DanielS Avatar answered Mar 06 '23 19:03

DanielS