简体   繁体   中英

How to Compress Jpeg file to a limited size (e.g 200KB) without losing much image quality

I wish to reduce image size around 200KB before save into database. Let say I have a bitmap file around 39MB, I need to convert Bitmap to Jpeg and then reduce the Jpeg file <= 200KB (all type of graphics file are possible to convert (eg bmp, jpg, png), but final graphic type will be Jpeg lesser than 200KB). I'm writing the following code try to convert (in this case i set the jpg quality to 10 since i want the file size to be 200KB):

    function BMPtoJPG(var BMPpic, JPGpic: string):boolean;
    var Bitmap: TBitmap;
        JpegImg: TJpegImage;
    begin
      Result:= False;
      Bitmap := TBitmap.Create;
      try
        Bitmap.LoadFromFile(BMPpic) ;
        JpegImg := TJpegImage.Create;
        try
          JpegImg.CompressionQuality := 10; //in this case i set the quality to 10 so the file size will be around 200KB)
          JpegImg.Assign(Bitmap);
          JpegImg.Compress;
          JpegImg.SaveToFile(JPGpic) ;
          Result:=True;
        finally
          JpegImg.Free
        end;
      finally
        Bitmap.Free;
      end;
    end;

I use the same image file to convert in Adobe Lightroom program in export dialog limit the size to 200KB and compare with the image converted by the above function BMPtoJPG. The quality image from Adobe Lightroom is much more better than the function method (both file size around 200KB)

Can anyone show me how to write code reduce image size (limit size to 200KB) while the quality doesn't drop much.

Thanks and appreciate for your answer.

If your goal is to have a smaller file content, you can first resize the bitmap, then apply a better CompressionQuality rate.

As a result, the global quality of the image would probably be better.

The TJpegImage relies on the standard libjpeg library, whereas I suppose that Adobe has its own tuned implementation. You can try other implementations, like the one included in GDI+ , or a pure pascal implementation or even old Intel's library .

See if your encoder support sampling. If you sample your Cb and Cr components at a lower rate than the Y component, you can often get better compression with out a lot of quality loss. If you do 4:1:1 you cut the amount of data to compress nearly by a third. 2:1:1 cuts it by half.

This technique called chroma subsampling . Unfortunately, Delphi's stock TJpegImage wrapper around IJG implementation ver. 6b does not expose this capability and initializes encoder context to all-default values which corresponds to 4:2:0. Refer to TJPEGImage.Compress method code, libjpeg documentation and jpeglib.h or JPEGLIB.PAS from the pasjpeg package, if you prefer (latter is merely straightforward translation of IJG implementation ver. 6a to Pascal).

Also, you can migrate to the one of other implementation. In addition to @Arnaud Bouchez list, it is worth to mention yet another Pascal implementation available to reuse: http://www.colosseumbuilders.com/sourcecode

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM