Groups | Blog | Home
all groups > dotnet drawing api > june 2005 >

dotnet drawing api : DrawImage and Out Of Memory



Peter Laurinc
6/23/2005 12:00:00 AM
Hi,

I have problem with drawing large bitmaps.

There is firstBitmap 32bppARGB for offscreen drawing sized cca 1000x700
pixels.
From file I load secondBitmap 1bppIndexed sized ccz 9000x14000. I want to
draw second bitmap scaled to first bitmap.

I get graphics from firstBitmap and set it appropiate transform matrix. then
I use

Graphics g = Graphics.FromImage(firstBitmap);
Matrix m = new Matrix();
m.Scale(0.05, 0.05);
g.DrawImage(secondBitmap, 0, 0).

I always get Out Of Memory on this line.
Also in any operation with second bitmap.
When I try to save second bitmap to BMP file, file is saved OK and is sized
cca 16MB.

Anybody helps?

Thanks

Peter

gOODiDEA
6/28/2005 12:00:00 AM
Graphics g = Graphics.FromImage(firstBitmap);
Matrix m = new Matrix();
m.Scale(0.05, 0.05);
g.DrawImage(secondBitmap, 0, 0).

==>
g.Dispose();

after you don't use firstBitmap or secondBitmap,you should dispose them

firstBitmap.Dispose();
secondBitmap.Dispose();

[quoted text, click to view]

Peter Laurinc
6/29/2005 12:00:00 AM
it is pseudo code.

Do you think that creating newBitmap sized as first (32bpp) but in 1bpp,
draw large bitmap into it and then draw this small 1bpp into 32bpp is a
solution?

Anyway, I will check it

Thanks

[quoted text, click to view]

Peter Laurinc
6/29/2005 8:42:26 AM
I don't think that problem is in disposing bitmaps (beacuse it throws out of
memory when drawing one bitmap to another -> I can't dispose any of that
bitmaps before drawing).
It seems, that when you are drawing 1bpp bitmap it is first converted to
32bpp => Out of memory because at this size it takes cca 480 MB of memory.

Anyone knows, how GDI+ draws images? Especially i they are in diferrent
PixelFormat?

[quoted text, click to view]

Scott McChesney
6/29/2005 9:16:31 AM
Since your target bitmap is a 32bpp ARGB, GDI+ will have to convert your
1bpp indexed image into 32 bpp ARGB before it can draw it. I don't know
this for sure, but I wouldn't be surprised if GDI+ has to convert your
entire source bitmap before it can scale it and draw it into your target
bitmap. That means you're trying to convert a 9000x14,000 bitmap, which -
at 4 bytes per pixel - is where your 480+ MB is coming from.

By the way - I see where your Matrix object is created and scaled, but I
never see where it's applied to any of your Graphics objects...

HTH

- Scott

[quoted text, click to view]

Scott McChesney
6/29/2005 11:13:40 AM
OK - just checking. I've set up a Matrix and then forgot to apply it to the
Graphics object enough times to ask...

If I understand what you want to do, it would look something like this:

1. Create a 1bpp bitmap the size of your 32bpp target.
2. Draw your source 1bpp bitmap into the target 1bpp bitmap, using your
scaling matrix.
3. Draw the 1bpp result from #2 into your 32bpp bitmap.

Using that process, I would think you'd be OK, since you're down to roughly
2 MB images for your 32bpp target. My only concern would be if GDI+ can
work natively with 1bpp images. If it can, it should be smart enough to
realize that no conversion is necessary. However, since you are scaling the
image down, it might try to convert the image into some other format for the
scaling algorithm, scale it, and convert it back. Under that scenario,
you're probably out of luck, unless it picks a relatively small format to
use. That seems like a dumb thing to do, but I don't know how GDI+ manages
the different formats.

Bob Powell would know much more than I on this, but ultimately you'll just
want to try it and see.

HTH

- Scott

[quoted text, click to view]

Peter Laurinc
6/30/2005 12:00:00 AM
It seems that .NET can't handle operations (resize) of indexed images
without translating them to 32bpp.

[quoted text, click to view]

Scott McChesney
6/30/2005 12:21:37 PM
That doesn't necessarily surprise me... the algorithms are a lot easier to
write using a consistent format. Why they chose 32bpp - well, I have a
guess. Given that they seem to be choosing to work with a non-indexed
format, their choices are 16, 24, or 32bpp. Caution says you use the
largest format you can.

As I said, I'm not an expert on this. You might peruse Bob Powell's site,
to see if he has any suggestions. I have heard of something called
"FreeLibrary" (I think), which is supposedly designed to work with large
images in .NET. You might check that out and see if you can get it to work
for you. If not, then you're probably SOL. Sorry...

- Scott

[quoted text, click to view]

Peter Laurinc
7/1/2005 10:46:22 AM
We have found solution - hack

we load large bitmap in 1bppi and then split it to 1bppi chunks to cca 8M
pixels -> 32MB of memory in 32bpp when they are drawed.
It works ok at reasonable speed

[quoted text, click to view]

Scott McChesney
7/5/2005 11:13:03 AM
IIRC, I believe that's the basis of the "FreeLibrary" programming I was
talking about. Either way, while it might be considered a "hack", it's
about the only method you have.

Glad you found a solution.

- Scott

[quoted text, click to view]

AddThis Social Bookmark Button