0

I got this exception when I am trying to do this:

        var pixels = await bitmap.GetPixelsAsync();
        byte[] bytes = pixels.ToArray();

It occurs at pixels.ToArray(). The information here doesn't help me too much. I only know that the length and capacity of my pixels are 0 but I don't know why and how to fix that.

The context of this piece of code:

    public static async Task<string> SaveThumbnail(UIElement image, bool isCurrent)
    {
        var bitmap = new RenderTargetBitmap();
        try
        {
            await bitmap.RenderAsync(image);
        }
        catch (ArgumentException)
        {
            return "";
        }
        var pixels = await bitmap.GetPixelsAsync();
        byte[] bytes = pixels.ToArray();
        // some other code
    }

This function is was called here:

    public static async Task<Brush> GetThumbnailMainColor(UIElement image, bool isCurrent)
    {
        var filename = await SaveThumbnail(image, isCurrent);
        var file = await ThumbnailFolder.GetFileAsync(filename);
        return await ColorHelper.GetThumbnailMainColor(file);
    }

And it is called here:

        thumbnail.Source = thumbnails.Count == 0 ? Helper.DefaultAlbumCover : thumbnails[random.Next(thumbnails.Count)];
        grid.Background = await Helper.GetThumbnailMainColor(thumbnail, false);

I set the Image source right before the call and I am pretty sure I can see the image displayed in thumbnail. So why do I get 0-Capacity pixels?

Seaky Lone
  • 992
  • 1
  • 10
  • 29
  • can it be because you call `RenderAsync` in `try` block? (scope limitations maybe?). RenderAsync is not supposed to throw an exception according to documentation, so you could remove your try block. – Antoine Sep 04 '19 at 05:33
  • @Antoine I also don't know why it gives my an `ArgumentException` sometimes so I have to keep it. I guess the image is being used somewhere else and not available for using, which might cause that exception. – Seaky Lone Sep 04 '19 at 05:42

1 Answers1

1

Maybe you render RenderTargetBitmap too quick after setting the source of the thumbnail (Is it Image control?), and the image is not yet rendered on the interface, which will result in you not getting the image inside the Image.

Try this:

thumbnail.Source = thumbnails.Count == 0 ? Helper.DefaultAlbumCover : thumbnails[random.Next(thumbnails.Count)];
thumbnail.Loaded += async (_s,_e) =>
{
    grid.Background = await Helper.GetThumbnailMainColor(thumbnail, false);
}

Best regards.

Richard Zhang
  • 7,523
  • 1
  • 7
  • 13
  • Thank you! This solution works! But why do I fail to put it in the xaml of `Image`? Like if I do `` I still got the same exception. And how can I make use of your code if it is in the `DataTemplate`? – Seaky Lone Sep 04 '19 at 09:08
  • Specifically, how if I set the thumbnail source in a converter, how can I subsequently set the grid.background? – Seaky Lone Sep 04 '19 at 09:22
  • If it is for your later question, you can consider setting a static variable that the `Converter` can access externally, listening to the value of this variable, and rebinding the Image's Loaded event when the condition is met. Change the value of this static variable after setting the source. But I don't know how you wrote the code, and Image doesn't provide a `SourceChanged` event, so I don't think it's a good idea to implement RenderTargetBitmap dynamically in the DataTemplate. – Richard Zhang Sep 04 '19 at 09:42