I'm working on a personal project that creates an single image from a grid of images. It takes a while to generate the image and doesn't refresh everytime only once the code is done executing. How can the make the interface still functional (not locked up) when its generating the image.
So to start: I have a N x N grid of identifiers, based on the identifier I draw a specific image at (x,y) with a given scaled height and width.
This image is regenerated each iteration and needs to be updated on the WPF. It is also bound to the ImageSource of the Image on the xaml side
My issue is 'How do I improve performance of generating this large image' and 'How do I refresh the image as many times as I need to (per generation).
for (int i = 0; i < numberOfIterations; i++)
{
// Do Some Work
UpdateIm开发者_Python百科age();
}
...
BitmapImage imgFlower = new BitmapImage(new Uri(@"Images\Flower.bmp", UriKind.Relative));
BitmapImage imgPuppy = new BitmapImage(new Uri(@"Images\Puppy.bmp", UriKind.Relative));
ImageSource GeneratedImage{ get{ GenerateImage(); } set; }
...
void UpdateImage() { OnPropertyChanged("GeneratedImage"); }
...
ImageSource GenerateImage()
{
RenderTargetBitmap bmp = new RenderTargetBitmap(223, 223, 96, 96, PixelFormats.Pbgra32);
DrawingVisual drawingVisual = new DrawingVisual();
using (DrawingContext drawingContext = drawingVisual.RenderOpen())
{
double scaleRatio = CalculateScaleRatio();
DrawGridOfImages(drawingContext, scaleRatio);
}
bmp.Render(drawingVisual);
return bmp;
}
...
DrawGridOfImages(...)
{
double x,y;
for (int r = 0; r < NumberOfRows; r++)
{
x = r * scaleRatio;
for (int c = 0; c < NumberOfColumns; c++)
{
y = c * scaleRatio;
switch (imageOccupancy[r, c])
{
case Flower: drawingContext.DrawImage(imgFlower, new Rect(x,y,scaleRatio,scaleRation));
case Puppy: drawingContext.DrawImage(imgPuppy, new Rect(x,y,scaleRatio,scaleRatio));
}
}
}
}
There are two ways. To first and most beneficial would be to improve the perceived performance, do this by generating the image on a worker thread and use events to update the image on the UI thread at key points so your users can see the progress.
To improve actual performance, if you are targeting and using multicore systems you can try parallel functions if your iterations can actually be performed in parallel. This will require some work and a different mindset but will help if you put the effort in. I'd recommend studying PLINQ to get started.
精彩评论