none
Performance problem when displaying a grid of bitmap images

    Question

  • Hello there,

    My application needs to display a grid of bitmap images on the screen. Trying everything I could think of, my application still doesn't feel snappy. So I built a simplified sample to test the issue. I used a timer to calculate how long my "display images" event handler executed, and used a stop watch to measure how long it took for the images to appear on the screen. The bottom line: when displaying 10x10, 40x40, 50x50 and 60x60 grids of images, WPF took 2, 9, 12 and 16 seconds to display the images on the screen after my event handling code had finished. So I feel helpless: It seems I can't improve my code to make the images appear faster - I need to do something with WPF!

    So my question is: What do I need to do differently to make the images display faster?


    The test setup is simple:

    The window contains a Grid. After the "test" button is clicked, row and column definitions are added to the grid, and an Image control is added to each cell of the grid as follows:

                var image = new Image(); 
                image.BeginInit(); 
                image.Name = ImageNameFromCell(theRow, theColumn); 
                image.Stretch = Stretch.None; 
                image.HorizontalAlignment = HorizontalAlignment.Center; 
                image.VerticalAlignment = VerticalAlignment.Center; 
                RenderOptions.SetBitmapScalingMode(image, BitmapScalingMode.LowQuality); 
                image.EndInit(); 
     
                theGrid.Children.Add(image); 
    

    Next, the Source of each image is set to a bitmap: a gray-scale image scaled down to the estimated screen size of a cell. The bitmap is generated as follows:

                var smallerBitmapImage = new BitmapImage(); 
                smallerBitmapImage.BeginInit(); 
                smallerBitmapImage.DecodePixelWidth = (int)(theImageWidth); 
                smallerBitmapImage.UriSource = theUri; 
                smallerBitmapImage.CacheOption = BitmapCacheOption.None; 
                smallerBitmapImage.EndInit(); 
     
                //BitmapFrame bitmapFrame = BitmapFrame.Create(this.FullPath); 
     
                var convertedBitmap = new FormatConvertedBitmap(); 
                convertedBitmap.BeginInit(); 
                convertedBitmap.Source = smallerBitmapImage; 
                convertedBitmap.DestinationFormat = PixelFormats.Gray16; 
                convertedBitmap.EndInit(); 
                convertedBitmap.Freeze(); 
    

    AFAIU this means that when my event handler code returns, all images have been read from the disk (which is SSD, anyhow) and reside in memory as bitmaps. There're no dependencies, nothing to do: Just a bunch of images in an array, with scaled down bitmaps already loaded to memory. The Image controls are instructed not to scale the images (and to use low quality scaling, at that :). Additionally the images are frozen. Still, it takes WPF a noticeable delay to display them.

    Any suggestions?

    Tuesday, February 14, 2012 6:12 AM

Answers

All replies

  • Hi AvinAtBezeqint,

    Firstly, you could use this WPF performace tool to test your WPF application, and then you could know which part cost so much time, the download link is:

    http://msdn.microsoft.com/en-us/library/aa969767.aspx

    and there is also a WPF performance article you could refer to:

    http://msdn.microsoft.com/en-us/library/aa970683.aspx

    As for your main concern, you could use DrawingContext, it will be better:

    http://msdn.microsoft.com/en-us/library/system.windows.media.drawingcontext.aspx

    http://msdn.microsoft.com/en-us/library/system.windows.media.drawingvisual.aspx

     private DrawingVisual CreatObjects()
    {
                DrawingVisual visual = new DrawingVisual();
    
                using (DrawingContext dc = visual.RenderOpen())
    
                {
                        dc.DrawRectangle(Brushes.Brown, new Pen(Brushes.Black, 1), new Rect(i, i, 200, 200));
                        // dc.DrawRectangle(Brushes.Brown, new Pen(Brushes.Black, 1), new Rect(i, i, 200, 200));
    
                        BitmapImage image = new BitmapImage();
                        // image.StreamSource 
    
                        image.BeginInit();
     
                        image.UriSource = new Uri("..\\..\\Images\\1.png", UriKind.Relative);
    
                        image.DecodePixelWidth = 100;
    
                        image.DecodePixelHeight = 100;
    
                        image.EndInit();
    
                        image.Freeze();
    
    
                        dc.DrawImage(image, new Rect(i, 10, 100, 100));
                }
         return visual;
    }

    Best regards,


    Sheldon _Xiao[MSFT]
    MSDN Community Support | Feedback to us
    Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Wednesday, February 15, 2012 7:06 AM
    Moderator
  • Hi  AvinAtBezeqint,

    I am marking your issue as "Answered", if you have new findings about your issue, please let me know.

    Best regards,


    Sheldon _Xiao[MSFT]
    MSDN Community Support | Feedback to us
    Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Friday, March 09, 2012 6:41 AM
    Moderator