i am working on an WPF image viewer with a photo collage mode. Therefore some images from a folder on hdd should be displayed on random positions on a canvas by adding image after imaging in a certain time interval. The images have a fixed target size, which they should be scaled to, but they should keep their aspect ratio.
At the moment i am testing my app with 2 mb images, which increases memory consumption pretty quick, so that i get an outofmemoryexception after about 40 images on the canvas.
This is some sample code how i load, resize and add the images atm:
void timer_Tick(object sender, EventArgs e)
{
string imagePage = foo.getNextImagePath();
BitmapImage bi = loadImage(imagePath);
int targetWidth = 200;
int targetHeight = 200;
Image img = new Image();
resizeImage(targetWidth, targetHeight, bi.PixelWidth, bi. PixelHeight, img);
img.Source = bi;
// random position
double left = RandomNumber.getRandomDouble(leftMin, leftMax);
double top = RandomN开发者_如何转开发umber.getRandomDouble(topMin, topMax);
Canvas.SetLeft(image, left);
Canvas.SetTop(image, top);
imageCanvas.Children.Add(image);
}
private BitmapImage loadImage(string imagePath)
{
bi = new BitmapImage();
bi.BeginInit();
bi.UriSource = new Uri(imagePath, UriKind.Absolute);
bi.CacheOption = BitmapCacheOption.Cache;
bi.EndInit();
return bi;
}
private void resizeImage(double maxWidth, double maxHeight, double imageWidth, double imageHeight, Image img)
{
double newWidth = maxWidth;
double newHeight = maxHeight;
// calculate new size with keeping aspect ratio
if (imageWidth > imageHeight)
{// landscape format
newHeight = newWidth / imageWidth * imageHeight;
}
else
{// portrait format
newWidth = newHeight / imageHeight * imageWidth;
}
img.Width = newWidth;
img.Height = newHeight;
}
I would like to know how i could reduce the memory usage. Maybe resizing directly on creation of the BitmapImage? Any thoughts would be appreciated! Thanks in advance.
BTW i am aware that the memory consumption will increase by the number of images, therefore it is planned to limit the number of images in the canvas and remove the oldest image when adding another one. But first i have to figure out what the best and maximum numbers of images are that i can display on a canvas.
Whilst the images that you're loading during testing are 2MB in size, I expect that this is 2MB file size, and the in-memory representation of these files is probably many times this amount. If you're taking files that are e.g. 1000x1000 and resizing these to 200x200, I don't see any need to keep the larger representation in memory - so I would say you're best placed to resize the BitmapImage objects themselves rather than having the Image objects scale them when rendering (currently, the full size BitmapImage objects will still be in memory, as they're attached to the Image.Source).
If you've the image paths stored somewhere you can always reload the full size images at a later date should the resized size change.
精彩评论