Jump to content
Attila Kovacs

TBitmap32 to jpg (graphics32)

Recommended Posts

How can I save the image from a TBitmap32 into a jpg (actually to the same type it was before loading, but let's start with jpg) without involving a TBitmap?

 

Edited by Attila Kovacs

Share this post


Link to post
30 minutes ago, David Heffernan said:

I'm confused. The VCL ships with a JPEG encoder. 

Yeah, kinda, I don't know the internals, but that needs TBitmap which causes me gigabytes of unreleased RAM if I'm using it from threads.

I could not find any info on that either.

Share this post


Link to post
1 hour ago, Attila Kovacs said:

don't know the internals, but that needs TBitmap

Not necessarily. In my Image32 graphics library, I'm using Delphi's JPEG unit without touching TBitmap.

 

Edit: Sorry, the JPEG unit does use TBitmap.

Edited by angusj
  • Thanks 1

Share this post


Link to post
13 minutes ago, angusj said:

Not necessarily. In my Image32 graphics library, I'm using Delphi's JPEG unit without touching TBitmap.

Wow man, thank you for pointing this out, this is a remarkable library indeed, just what I was looking for.

The endless memory consumption of TBitmap is hereby solved.

Share this post


Link to post
1 hour ago, angusj said:

Edit: Sorry, the JPEG unit does use TBitmap.

I see, still, something is different, memory is released asap.

 

With your lib, in 8 threads, converting 13GB/5200 jpg's the application takes 500MB-1GBPeak RAM.

With my converter, TPicture.LoadFromFile, DrawTo TBitmap, Resize to another TBitmap, assign to JPEGImage, save: RAM is linear up to 13GB+.

There is no memory leak, something in Windows is holding some working RAM or whatever. I don't care anymore. 

 

Edited by Attila Kovacs

Share this post


Link to post
6 hours ago, Attila Kovacs said:

How can I save the image from a TBitmap32 into a jpg (actually to the same type it was before loading, but let's start with jpg) without involving a TBitmap?

This one seems to do just that: https://github.com/taazz/simdesign/blob/87fdcc43f3a71016280cdbfc11de6cf4dd836254/simlib/nativejpg/NativeJpg32.pas

Haven't tried it though.

Share this post


Link to post
2 hours ago, Attila Kovacs said:

With your lib, in 8 threads, converting 13GB/5200 jpg's the application takes 500MB-1GBPeak RAM.

With my converter, TPicture.LoadFromFile, DrawTo TBitmap, Resize to another TBitmap, assign to JPEGImage, save: RAM is linear up to 13GB+.

There is no memory leak, something in Windows is holding some working RAM or whatever. I don't care anymore. 

Thanks, I'm very pleased to hear that. And I'm now curious as to how the performance compares with your converter?

Also, I could fairly easily modify Delphi's JPEG unit to expose the functions in the JPEG OBJ files and bypass TBitmap entirely but I'm not sure it's worth the effort thought it could improve performance .

Share this post


Link to post

I just tried NativeJpg32, and while it has quite a few more dependencies (on the other SimDesign units) than what I would have liked, it worked well on everything I threw at it.

 

With regard to memory usage I tried loading a 16.4 Gb jpeg file (7900x5430 pixels) into a TBitmap32. The TBitmap32 as expected consumed 163 Mb. The peak overhead during load and conversion was 600 Mb.

Loading the same image as a BMP into TBitmap32 and then converting it to JPEG caused a peak overhead during conversion of 675 Mb and resulted in a jpg filesize of 11.1 Mb. Of course the two file were no longer identical due to the lossy jpeg encoding.

 

I did not experience any leaks.

Share this post


Link to post

Sorry if this is not related to your problem, but have you tried using TWICImage ?
 

Share this post


Link to post
2 hours ago, Anders Melander said:

a few more dependencies ... than what I would have liked

Very PC. I lost my patience after the 3rd dependency, however, looking into the sources it is quality work indeed.

I'll check the speed against TImage32 when I found some time.

Share this post


Link to post
2 hours ago, Clément said:

Sorry if this is not related to your problem, but have you tried using TWICImage ?

Never heard of it. Is it already in Berlin?

Share this post


Link to post

I'm using since Delphi XE :classic_smile:

Should be in VCL.Graphics unit.

Edited by Clément

Share this post


Link to post
42 minutes ago, David Heffernan said:

I'm not aware that the VCL jpeg unit leaks. How are you measuring that? 

Who are you talking to?

Nobody said that it leaks, but somehow something won't release some memory until the app is closed, thus, it can not be used in a service.

Measure? ctrl-shift-escape, there you can measure. Or you can wait until the out of resources dialog.

Share this post


Link to post
8 minutes ago, Attila Kovacs said:

Or you can wait until the out of resources dialog.

That would be due to a leak.

 

Again though, I'm not aware that the VCL jpeg code leaks anything. Am I missing something? 

Share this post


Link to post
1 minute ago, David Heffernan said:

That would be due to a leak.

 

Well, it's not my problem anymore. @angusj provided a solution to overcome that.

Share this post


Link to post

Most likely if there was a leak it was in your code, that would be my best guess. 

Edited by David Heffernan

Share this post


Link to post

It's always your best guess and I don't have any other ideas either, but I don't know the internals and the Delphi manual is also very limited. 

Anyway, I can't invest any more time into this to figure it out myself and the solution I got I like much more as it skips an unnecessary step.

Edited by Attila Kovacs

Share this post


Link to post
18 minutes ago, Attila Kovacs said:

It's always your best guess.

In fairness, I think David asks a valid question. While it's certainly possible this presumed leak is due to a bug in Delphi code, based on probabilities it's much more likely in your code. Even though it's now working (without TJpegImage or whatever), it's likely still there, just not currently causing problems. If a short term fix is all you need then that's great. But it you're counting on this to work in a presumably unattended server long term, it's usually better to invest the time to find out the definitive cause now than have things blow up later when it's far less convenient.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×