Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Loading multi-megapixel photos as thumbnails in CF

3 views
Skip to first unread message

Tor Helland

unread,
Apr 11, 2006, 3:43:09 AM4/11/06
to
I'm struggling with .Net CF, and when I try to load photos and display
them as thumbnails (only one at a time), that works twice. After that I
get exceptions.

I'm calling "GC.Collect" before loading the bitmap. Without that I got
no thumbnails at all.

I tried calling ImageLoader.dll taken from an MSDN article [1]. That
wouldn't load my bitmaps. I tried using some code in OpenNetCF.org SDF
2.0 beta, but that is probably .Net 2.0 specific [2].

What is a good way to solve this thumbnail feature? Should I stop
whining, double-check to make sure my code doesn't gobble memory, and
it'll just work ;-)


[1] http://msdn.microsoft.com/msdnmag/issues/04/12/NETCompactFramework/

[2] Thread "OpenNetCF SDF 2 beta in Delphi 2006"

-tor

Craig Stuntz [TeamB]

unread,
Apr 11, 2006, 10:04:28 AM4/11/06
to
Tor Helland wrote:

> I'm struggling with .Net CF, and when I try to load photos and display
> them as thumbnails (only one at a time), that works twice. After that
> I get exceptions.

Do you really want to load an entire multi-MP image in a CF device for
the purpose of displaying a thumbnail? I realize it's a pain, but ISTM
you should find or write a class which only loads enough data to render
the thumbnail, not the entire image.

--
Craig Stuntz [TeamB] · Vertex Systems Corp. · Columbus, OH
Delphi/InterBase Weblog : http://blogs.teamb.com/craigstuntz
Borland newsgroup denizen Sergio González has a new CD of
Irish music out, and it's good: http://tinyurl.com/7hgfr

Marc Rohloff [TeamB]

unread,
Apr 11, 2006, 7:33:52 PM4/11/06
to
On 11 Apr 2006 00:43:09 -0700, Tor Helland wrote:

> I'm struggling with .Net CF, and when I try to load photos and display
> them as thumbnails (only one at a time), that works twice. After that I
> get exceptions.

Can you show us the code you are using?

--
Marc Rohloff [TeamB]
marc rohloff -at- myrealbox -dot- com

Tor Helland

unread,
Apr 12, 2006, 3:36:23 AM4/12/06
to
Craig Stuntz [TeamB] is rumoured to have said:

> Tor Helland wrote:
>
> > I'm struggling with .Net CF, and when I try to load photos and
> > display them as thumbnails (only one at a time), that works twice.
> > After that I get exceptions.
>
> Do you really want to load an entire multi-MP image in a CF device
> for the purpose of displaying a thumbnail? I realize it's a pain, but
> ISTM you should find or write a class which only loads enough data to
> render the thumbnail, not the entire image.

At first I did that, but had to look for other solutions, like the
OpenNetCF.org SDF 2.0 beta [1]. I haven't got that working yet, as it
uses CF2.


[1] http://blog.opennetcf.org/afeinman/default,date,2006-02-03.aspx

-tor

Tor Helland

unread,
Apr 12, 2006, 7:58:14 AM4/12/06
to
Marc Rohloff [TeamB] is rumoured to have said:

> On 11 Apr 2006 00:43:09 -0700, Tor Helland wrote:
>
> > I'm struggling with .Net CF, and when I try to load photos and
> > display them as thumbnails (only one at a time), that works twice.
> > After that I get exceptions.
>
> Can you show us the code you are using?

Yes, here it is. Photo is an object containing info about the jpeg
file. picPhoto is a System.Windows.Forms.PictureBox, created when the
form is created. I tried doing a bmp.Free at the end, but that didn't
help, and I think .Net does that for me.


procedure dlgEdit.SetPhoto(const Value: TPhoto);
var
bmp: System.Drawing.Bitmap;
begin
if not Assigned(Value) then
raise Exception.Create('SetPhoto (nil)');
if not System.IO.File.Exists(Value.FullName) then
raise Exception.Create('SetPhoto ' + Value.FullName);

FPhoto := Value;

lblFileName.Text := Photo.DisplayName.ToLower;
edtSapId.Text := Photo.SapId;
edtComment.Text := Photo.Comment;

// Load bitmap, and try to avoid Out Of Memory
try
bmp := Bitmap.Create(Photo.FullName);
except
GC.Collect;
try
bmp := System.Drawing.Bitmap.Create(Photo.FullName);
except
// Out Of Memory - let it pass
Exit;
end;
end;

// Put the image on screen
picPhoto.SizeMode := PictureBoxSizeMode.StretchImage;
picPhoto.Image := bmp;
end;


-tor

Craig Stuntz [TeamB]

unread,
Apr 12, 2006, 8:30:08 AM4/12/06
to
To do a full collection you need to call GC.Collect, then
GC.WaitForPendingFinalizers and then GC.Collect again. But I *really*
think that this is the wrong thing to do.

Also, as your code doesn't check the exception class it will fire off
GC.Collect if the file is in invalid format, if it's locked, etc., etc.

Also, System.Drawing.Bitmap inherits from System.Drawing.Image, which
inherits IDisposable, and I can't see where you ever dispose of the
bitmaps you're creating. In Delphi the easiest way to do this is by
calling Free.

--
Craig Stuntz [TeamB] · Vertex Systems Corp. · Columbus, OH
Delphi/InterBase Weblog : http://blogs.teamb.com/craigstuntz

All the great TeamB service you've come to expect plus (New!)
Irish Tin Whistle tips: http://learningtowhistle.blogspot.com

Tor Helland

unread,
Apr 12, 2006, 10:39:57 AM4/12/06
to
Craig Stuntz [TeamB] is rumoured to have said:

> To do a full collection you need to call GC.Collect, then

> GC.WaitForPendingFinalizers and then GC.Collect again. But I really


> think that this is the wrong thing to do.

Thank you, and yes, it feels like fixing symptoms of a problem, not the
problem. But the extra GC calls didn't affect the behaviour. And the
logged numbers from GC.GetTotalMemory were pretty much the same.

> Also, as your code doesn't check the exception class it will fire off
> GC.Collect if the file is in invalid format, if it's locked, etc.,
> etc.

The exception I keep getting is a System.Exception, with Message =
"Exception". And the same with GetBaseException, and no InnerException.

> Also, System.Drawing.Bitmap inherits from System.Drawing.Image, which
> inherits IDisposable, and I can't see where you ever dispose of the
> bitmaps you're creating. In Delphi the easiest way to do this is by
> calling Free.

I have the impression that these pointers in .Net behave like
interfaces, disposing when they go out of scope. Like in the Borland
.Net Chat demo, where the about form is created but seemingly
automatically freed.

Anyway the behaviour and numbers from GC.GetTotalMemory stayed the same
when I added "bmp.Free".


Btw, I'm testing this on a Windows Mobile 5, Qtek 9000.

-tor

Craig Stuntz [TeamB]

unread,
Apr 12, 2006, 10:48:03 AM4/12/06
to
Tor Helland wrote:

> > Also, System.Drawing.Bitmap inherits from System.Drawing.Image,
> > which inherits IDisposable, and I can't see where you ever dispose
> > of the bitmaps you're creating. In Delphi the easiest way to do
> > this is by calling Free.
>
> I have the impression that these pointers in .Net behave like
> interfaces, disposing when they go out of scope. Like in the Borland
> .Net Chat demo, where the about form is created but seemingly
> automatically freed.

No. If you don't understand why you should Dispose objects which
implement IDisposable, you *really* need to read up on this. Yes, the
GC will eventually clean up after you if you don't, but you do not want
to rely on that on a memory-challenged device like a PDA.

--
Craig Stuntz [TeamB] · Vertex Systems Corp. · Columbus, OH
Delphi/InterBase Weblog : http://blogs.teamb.com/craigstuntz

IB 6 versions prior to 6.0.1.6 are pre-release and may corrupt
your DBs! Open Edition users, get 6.0.1.6 from http://mers.com

Marc Rohloff [TeamB]

unread,
Apr 12, 2006, 5:55:29 PM4/12/06
to
On 12 Apr 2006 04:58:14 -0700, Tor Helland wrote:

<snip>
I have to agree with Craig, using GC.Collect is never a good idea. Try
and solve the problem instead. Apart from reading up on the
IDisposable pattern you might find it useful to understand Unmanaged
Resources, Finalizers and Garbage Collection.

Your code should probably look something like:
bmp := Bitmap.Create;
try
{Use bitmap}
finally
bmp.Dispose;
end;

No GC.Collect necessary.
If you are going to assign the object to some other object (picPhoto)
you need to make sure that you dispose it whenever you have finished
with it.

0 new messages