ImageEn for Delphi and C++ Builder ImageEn for Delphi and C++ Builder

 

ImageEn Forum
Profile    Join    Active Topics    Forum FAQ    Search this forumSearch
Forum membership is Free!  Click Join to sign-up
Username:
Password:
Save Password
Forgot your Password?

 All Forums
 ImageEn Library for Delphi, C++ and .Net
 ImageEn and IEvolution Support Forum
 Jpg Compression question
 New Topic  Reply to Topic
Author Previous Topic Topic Next Topic  

whisper1980

USA
83 Posts

Posted - Feb 22 2021 :  15:40:12  Show Profile  Reply
I use ImageEnView to scale and recompress jpg images. I default to a 640 pixel width, JPEG_Quality of 80 and the ResampleFilter of Lanczos3.

A customer has both normal camera (Nikon) images and Infrared camera (FLIR) images. The IR jpg images scale down to about 1MB and the standard camera jpg scale down to about 70KB. This seems a bit odd and I don't know why the IR images are more than 10x the size of a normal scaled image (I don't yet know the size of the original image which I am trying to get from the customer)

Details on both show they are both 657x497, 24 bit depth. Standard image is 96dpi, IR is 72dpi. The only other difference based on the Windows details on an image is that the normal image has a compressed bits/pixel of 2 and the IR image shows nothing for that property.

Could this be the reason the IR image is so much larger than a standard camera image? If so, what ImageEnView.IO.Params would I use to produce the same value. I see SamplesPerPixel and BitsPerSample, but don't know if those will help.

Thoughts?

Eric

xequte

38690 Posts

Posted - Feb 22 2021 :  21:51:32  Show Profile  Reply
Hi Eric

(Excluding the rare case of gray-scale JPEG images) JPEG images are always full color, so playing with the bit depth is unlikely to have any meaningful effect.

The only factors for JPEG file size are:
- JPEG quality (including to a lesser extent, DCT method and Smoothing)
- Image dimensions
- Image content (uniformity of colors in particular)



Nigel
Xequte Software
www.imageen.com
Go to Top of Page

whisper1980

USA
83 Posts

Posted - Feb 23 2021 :  13:07:21  Show Profile  Reply
Something weird about the pictures taken with the FLIR infrared camera. I can use Paint.Net to load and save a 1.2MB FLIR jpg image as a BMP, and it is smaller, only 958KB. I can then save the BMP as a JPG with 100% quality and it is 224KB.

I can even skip the BMP conversion and just save the 1.2MB jpg image as a new JPG image, 100% quality, 4:2:2 chroma subsampling, and it is only 226KB. Saving it at 80% quality like I do in my app with ImageEN, the file is only 72KB, very much like the normal camera app images scale down to.

So I do not know what is going on with FLIR images, but Paint.Net does something different. All the values appear to be the same betweem the 1.2MB and 72KB images when looking at the Details tab for an image in Windows. Plus the images all look the same visually.

Any wild guesses on how to do whatever Paint.Net might be doing differently than ImageEn. I suppose you would need sample code to see what I'm doing in order to make a reasonable guess. I can send you the 1.2MB image if you want.

Eric
Go to Top of Page

xequte

38690 Posts

Posted - Feb 23 2021 :  15:48:34  Show Profile  Reply
Unfortunately I am unfamiliar with Paint.net. It sounds like it is doing some further processing behind the scenes when saving.

Nigel
Xequte Software
www.imageen.com
Go to Top of Page

whisper1980

USA
83 Posts

Posted - Feb 23 2021 :  18:11:50  Show Profile  Reply
FWIW, our old version of the program uses the old GR32, and it scales it right down to 56KB using about the same settings, 640 width, 80% quality and Lanczos resampler. For grins I also tried loading and saving the image as a new jpg using Windows Paint and it didn't make it smaller, but Snagit did (52KB).

Eric
Go to Top of Page

whisper1980

USA
83 Posts

Posted - Feb 23 2021 :  19:24:26  Show Profile  Reply
From what I've read, FLIR jpg images are actually "radiometric jpeg images" and contain Radiometric data (i.e. temperature data) embedded in each pixel.
https://flir.custhelp.com/app/answers/detail/a_id/1729/~/radiometric-jpeg-images

I think this is what is keeping the images large. So, with that in mind I added the following hack to my image import code and it takes care of the problem (the FLIR images down nicely as expected). I just hope to find a way to know if this data is present, maybe by reviewing the EXIF data so I don't have to do this for every jpg image I import.

If you know of a more efficient way to do this, it would be welcomed. I'm thinking it will lose the orientation data which is not good.

var vJpg := TJPEGImage.Create;
try
  vJpg.LoadFromFile(pFilename);
  var vBmp := TBitmap.Create;
  try
    vBmp.Width := vJpg.Width;
    vBmp.Height := vJpg.Height;
    vBmp.PixelFormat := pf24bit;
    vBmp.Canvas.Draw(0, 0, vJpg);
    vJpg.Assign(vBmp);
    var vStream := TMemoryStream.Create;
    try
      vJpg.SaveToStream(vStream);
      vStream.Position := 0;
      vImageEnView.IO.LoadFromStreamJpeg(vStream);
    finally
      FreeAndNil(vStream);
    end;
  finally
    FreeAndNil(vBmp);
  end;
finally
  FreeAndNil(vJpg);
end;

Eric
Go to Top of Page

whisper1980

USA
83 Posts

Posted - Feb 24 2021 :  09:52:16  Show Profile  Reply
This is what I ended up doing to remove the radiometrics. I tried a bunch of things, and this seemed the simplest and maintained the orientation even though I lose EXIF data (which I don't really need after the conversion, but might be nice to keep). If you have a better idea, let me know! :)

  IEGlobalSettings().IOParamDefaults.EnableAdjustOrientation := true;
...
  vImageEnView.IO.LoadFromFile(pFilename);
  var vFileType := vImageEnView.IO.Params.FileType;
  var vMake := String(vImageEnView.IO.Params.EXIF_Make);
  var vModel := String(vImageEnView.IO.Params.EXIF_Model);
  if (vFileType = ioJpeg) and (vMake.StartsWith('FLIR', true) or vModel.StartsWith('FLIR', true)) then
  begin
    var vStream := TMemoryStream.Create;
    try
      vImageEnView.IO.SaveToStreamBMP(vStream);
      vStream.Position := 0;
      vImageEnView.IO.LoadFromStreamBMP(vStream);
    finally
      FreeAndNil(vStream);
    end;
  end;


Eric
Go to Top of Page

xequte

38690 Posts

Posted - Feb 24 2021 :  16:36:10  Show Profile  Reply
Hi Eric

The upshot of your method seems to be just keeping the image data. This implies the excess size is due to embedded meta-data.

Does resetting it make any difference:

https://www.imageen.com/help/TIOParams.ResetInfo.html

Nigel
Xequte Software
www.imageen.com
Go to Top of Page

whisper1980

USA
83 Posts

Posted - Feb 24 2021 :  17:23:27  Show Profile  Reply
Well, that was a lot easier and much cleaner! I wish I knew about that a few hours/days ago, lol.
I did a ContainsInfo and it came back with [ierEXIF, ierJPEGMarkers]. Since I wanted to keep the EXIF data I issued ResetInfo([ierJPEGMarkers]) which takes care of it.

Resetting jpeg markers won't affect normal jpg images?

Thanks!

Eric
Go to Top of Page

xequte

38690 Posts

Posted - Feb 24 2021 :  19:06:01  Show Profile  Reply
Sorry Eric,

I didn't click earlier that this was a meta-data issue. Usually meta-data is quite small.

It's hard to say what data is lost when stripping JPEG markers because it can be custom, but I'd be surprised if you lost anything that was missed.



Nigel
Xequte Software
www.imageen.com
Go to Top of Page

whisper1980

USA
83 Posts

Posted - Feb 25 2021 :  12:44:57  Show Profile  Reply
No worries. It is always a learning experience trying to figure out how to solve a problem. I did learn a few things, so all good!

Eric
Go to Top of Page
  Previous Topic Topic Next Topic  
 New Topic  Reply to Topic
Jump To: