Various exceptions with Windows.Media.Import and retrieving thumbnails

Jos Huybrighs 336 Reputation points
2020-01-31T21:48:57.167+00:00

Hi,

I am using the Windows.Media.Import api to retrieve images from a mobile device connected over USB (using MTP) and showing them in a grouped GridView.

The code to retrieve thumbnails and show them is the following:

        private void OnGridViewContainerContentChanging(ListViewBase sender, ContainerContentChangingEventArgs args)  
        {  
            if (args.Phase == 0)  
            {  
                args.RegisterUpdateCallback(ShowThumbnail);  
                args.Handled = false;  
            }  
        }  

        private async void ShowThumbnail(ListViewBase sender, ContainerContentChangingEventArgs args)  
        {  
            if (args.Phase == 1)  
            {  
                var photoItemProps = args.Item as PhotoItemProperties;  
                try  
                {  
                    var thumbnailStream = await photoItemProps.ImportableItem.Thumbnail.OpenReadAsync();  
                    if (thumbnailStream != null)  
                    {  
                        var bitmapImage = new BitmapImage();  
                        bitmapImage.SetSource(thumbnailStream);  

                        var templateRoot = args.ItemContainer.ContentTemplateRoot as Grid;  
                        var image = templateRoot.Children[0] as Image;  
                        image.Source = bitmapImage;  
                    }  
                }  
                catch (Exception e)  
                { }  
            }  
        }  

Depending on the connected device, I am seeing 2 type of exceptions coming up when loading the thumbnails of the images:

  1. The System.Exception happens inside the Thumbnail.OpenReadAsync call and occurs when the device contains a lot of images (+3000 in my case, where most of them are music thumbnails generated by the VLC player on android).
    The exception message is: Exception from HRESULT: 0x80042010
  2. The System.OutOfMemoryException also happens inside OpenReadAsync and occurs on an older (a bit slower) device with just 200 pictures but lots of .webp images.
    The exception message is: Insufficient memory to continue the execution of the program. In both cases the exceptions don't seem to affect my app but in addition to the exception 2 other things don't seem to be correct:
    • In case of the +3000 pictures device all thumbnails come out well but scrolling in the GridView is really slow (unusable) when I scroll fast, e.g. by dragging the scrollbar handle. Scrolling row per row is acceptable.
    • In case of the older (slower) device most of the retrieved thumbnails are fixed placeholder thumbnails and not the real images. I think that this is an issue in the api implementation since I also see the same fixed placeholder images coming up in Microsoft's Windows Photo app when doing an import there.

So, my questions:

  • Are the exceptions normal?
  • Is there a reason why UWP apps would get placeholder thumbnails?
  • What methods can be used to make a grouped GridView more responsive when attached to a mobile device?

Jos

Universal Windows Platform (UWP)
{count} votes

Accepted answer
  1. Richard Zhang-MSFT 6,936 Reputation points
    2020-02-03T00:36:53.123+00:00

    Hello,​

    Welcome to our Microsoft Q&A platform!

    By examining your code, you can consider fixing some details, which should improve the responsiveness of your code.

    1. Please use BitmapImage.SetSourceAsync()

    Use asynchronous methods to keep the UI responsive and not get stuck.

    2. Please limit the resolution of BitmapImage

    Assume that the size of the Image control in your GridView is 200x200, but the resolution of the local image is 500x500. If you do not set the resolution, the application will load the 500x500 image, but only display the 200x200 area, which will greatly increase the memory consumption.

    Try this:

    var bitmapImage = new BitmapImage();
    bitmapImage.DecodePixelWidth = 200;
    await bitmapImage.SetSourceAsync(thumbnailStream);    
    

    3. Don't break the GridView's virtualization

    Virtualization can greatly reduce the memory burden because it only loads entries in the current window area. But if you add a layer of ScrollViewer outside the GridView, it will break the default virtualization.

    I don't know if you did a similar operation. If not, you can try the previous two methods, which should improve the performance of the application.

    Thanks.

    0 comments No comments

0 additional answers

Sort by: Most helpful