Job Runner ImageUsage Tracker Image
TransparentPadder

Share On FacebookShare On Facebook
 
Ben's Blog (57)Ben's Blog (57)
Development (13)Development (13)
Lisa's Blog (4)Lisa's Blog (4)
 
Show All (75)Show All (75)
 
Jan 2010 (3)Jan 2010 (3)
Nov 2009 (8)Nov 2009 (8)
Oct 2009 (4)Oct 2009 (4)
Sep 2009 (4)Sep 2009 (4)
Jul 2009 (6)Jul 2009 (6)
Jun 2009 (5)Jun 2009 (5)
May 2009 (7)May 2009 (7)
Mar 2009 (1)Mar 2009 (1)
Feb 2009 (5)Feb 2009 (5)
Jan 2009 (7)Jan 2009 (7)
Dec 2008 (6)Dec 2008 (6)
Oct 2008 (3)Oct 2008 (3)
Sep 2008 (3)Sep 2008 (3)
Aug 2008 (9)Aug 2008 (9)
Jul 2008 (3)Jul 2008 (3)
Jun 2008 (1)Jun 2008 (1)
 
Show All (75)Show All (75)
 
RSS & Atom FeedsRSS & Atom Feeds




TransparentPadder
Home  |  Shopping Cart (0)Blog  |  Highlights  |  Albums  |  Search  |  Contact  Atom & RSS Feeds

When and how to use the right BitmapCacheOption setting by Ben Vincent

I keep stumbling across the consequences of changing which BitmapCacheOption I use. Despite the fact that metadata in a file isn’t really that big in the grand scheme of things, changing which caching option you use can have annoying consequences. The two typical issues I run into are: running of our memory when process lots of files or not having any data to work with.

Let’s look at the code:

// The Metadata we'll be returning
BitmapMetadata bitmapMetadata;

// Open the stream, readonly
BitmapCreateOptions createOptions = BitmapCreateOptions.PreservePixelFormat | BitmapCreateOptions.IgnoreColorProfile;

// Create a decoder, cache all content on load because we'll close the stream
using (Stream sourceStream = File.Open(file, FileMode.Open, FileAccess.Read))
{
    // Create a Bitmap Decoder, loading all metadata on load
    BitmapDecoder bitmapDecoder = BitmapDecoder.Create(sourceStream, createOptions, BitmapCacheOption.OnLoad);

    // Grab the metadata
    bitmapMetadata = bitmapDecoder.Frames[0].Metadata.Clone() as BitmapMetadata;
}

If you use BitmapCacheOption.OnLoad then the decoder will load all the metadata into memory from the stream. When you Clone the BitmapMetadata you can safely close the stream with a full copy. That sounds great but it’s not fast and I’ve seen 20Mb of memory allocated per jpg photo, so pretty soon you’re running out of memory even on a decent machine. But if you use BitmapCacheOption.None, when you clone the BitmapMetadata and exit the using statement, there’s no metadata to play with!

So how do you make your code performant but still have data to use?

FotoFly solves this by grabbing all the most frequently used data from BitmapMetadata before throwing the stream away. The code below works by passing BitmapMetadata into a class that provides additional methods for reading\writing common attributes. Using reflection all the data is then copied across to a class that has no reliance on BitmapMetadata.

// The Metadata we'll be returning
PhotoMetadata photoMetadata = new PhotoMetadata();

BitmapCreateOptions createOptions = BitmapCreateOptions.PreservePixelFormat | BitmapCreateOptions.IgnoreColorProfile;

// Open the stream, readonly
using (Stream sourceStream = File.Open(file, FileMode.Open, FileAccess.Read))
{
    // Create a decoder with no cache options set
    BitmapDecoder bitmapDecoder = BitmapDecoder.Create(sourceStream, createOptions, BitmapCacheOption.None);

    // Create a new WpfMetadata class that exposes all the right fields
    WpfMetadata wpfMetadata = new WpfMetadata(bitmapDecoder.Frames[0].Metadata as BitmapMetadata);

    // Copy the common metadata across using reflection tool
    IPhotoMetadataTools.CopyMetadata(wpfMetadata, photoMetadata);
}

Even this doesn’t work when you’re loading hundreds of photos because Garbage Collection never appears to kick in. Under those circumstances I’ve found forcing Garbage Collection keeps the memory usage pretty low:

// Force Garbage Collection
GC.Collect();
GC.WaitForPendingFinalizers();

You can download FotoFly from Codeplex.


Posted: Sun, 8 Nov 2009, 09:25:51 GMT (Updated:  Sun, 8 Nov 2009, 10:42:19 GMT) by  Ben Vincent  |  0 Comments
Category: Development
Tags: FotoFly, Windows Imaging Component

 

 
TransparentPadderTransparentPadderTransparentPadder
TransparentPadder

Facebook Status  Ben Email decimated, unfortunately more like the Roman definition than the modern one.

(Updated: Wed, 3 Feb 2010, 00:22:01)
TransparentPadder
Alcatraz . American Express . Australia . Bing . Blue Angels . bmi . Breathe Magazine . British Food . Camping . Canada . Christmas . Christmas Tree . Cleaner Shrimp . CodePlex . Cooking . Coral Sea . Cycling . Diving . DragonLance . Engagement . Exif . Expedia . Facebook . Fire Shrimp . Firemen . Fish Tank . Fleet Week . Flying . Foie Gras . Food . FotoFly . GeoTagging . Giving Campaign . Golden Gate National Recreation Area . Google . Goose Fat . Gordon Ramsay . Hollywood . Hotmail . IPTC . Michelin Star . Microsoft . Monterey Bay Aquarium . Mountain Biking . Photography . San Francisco . Search Engine Optimzation . SEO . Silverlight . Tassography.com . TransRockies . United . Usage . Windows 7 . Windows Imaging Component . Windows Live . Windows Live Calendar . Windows Live Photo Gallery . Wineries . XMP

Sunday, January 24, 2010
- 2010-01-23 Lisa's Birthday

Sunday, January 17, 2010
- 2010-01-18 Things We Collect
- 2010-01-17 Weekend in Half Moon Bay

Saturday, January 16, 2010
- 2009-12-31 Holiday in Beaver Creek

Sunday, October 18, 2009
- 2009-10-10 San Francisco Fleet Week 2009

Sunday, October 04, 2009
- 2009-10-04 Biking Around The Bay

Sunday, August 30, 2009
- 2009-08-26 Caltrain
- 2009-08-22 Biking And Fracturing a Rib in Mammoth Lakes

Tuesday, August 11, 2009
- 2009-08-09 Biking on Pine Mountain

Wednesday, August 05, 2009
- 2009-08-01 Lisa's Mum and Sister Visit