Andrey Rubshtein
Andrey Rubshtein

Reputation: 20915

How can I implement lazy bitmap loading?

I want to write a function that will get as input string fileName and return an ImageDrawing object.
I don't want to load the Bitmap from the disk in this function. Instead, I want to have some kind of lazy evaluation. In order to find out the dimensions, I use the Bitmap class.

Currently I have this code:

    public static ImageDrawing LoadImage(string fileName)
    {
        System.Drawing.Bitmap b = new System.Drawing.Bitmap(fileName);
        System.Drawing.Size s = b.Size ;
        System.Windows.Media.ImageDrawing im = new System.Windows.Media.ImageDrawing();
        im.Rect = new System.Windows.Rect(0, 0, s.Width, s.Height);
        im.ImageSource = new System.Windows.Media.Imaging.BitmapImage(new Uri(fileName, UriKind.Absolute));
        return im;            
    }
  1. Is the call to System.Drawing.Bitmap constructor lazy?
  2. Is the call to .Size lazy?
  3. Is the BitmapImage constructor lazy?
  4. Is there any other way that I can implement it to be fully lazy?

Edit: There are many good answers that might be helpful to the community - to use Lazy class and to open it with a Task.
Nevertheless, I want to put this ImageDrawing inside a DrawingGroup and serialize afterwards, so Lazy as well as Task is not an option for me.

Upvotes: 2

Views: 909

Answers (2)

Markus Palme
Markus Palme

Reputation: 689

The constructor of the Bitmapclass is not lazy but you can use the Lazy<T> class which is made for exactly that purpose:

public static Lazy<ImageDrawing> LoadImage(string fileName)
{
    return new Lazy<ImageDrawing>(() => {
        System.Drawing.Bitmap b = new System.Drawing.Bitmap(fileName);
        System.Drawing.Size s = b.Size;
        System.Windows.Media.ImageDrawing im = new System.Windows.Media.ImageDrawing();
        im.Rect = new System.Windows.Rect(0, 0, s.Width, s.Height);
        im.ImageSource = new System.Windows.Media.Imaging.BitmapImage(new Uri(fileName,     UriKind.Absolute));
        return im;
    });
}

From the documentation (http://msdn.microsoft.com/en-us/library/dd997286.aspx):

Although you can write your own code to perform lazy initialization, we recommend that you use Lazy instead. Lazy and its related types also support thread-safety and provide a consistent exception propagation policy.

Upvotes: 4

NoWar
NoWar

Reputation: 37633

I suggest to use Timer within your class and download your image in a "lazy" manner. Also you can try to implement Task of MS TPL to do it as well inside of the Timer tick event.

Upvotes: 1

Related Questions