1

Okay, I'm trying to do some work analyzing heuristics of an image in a WPF app. When the user chooses the image file location, I want to open the image in the codebehind, check the colors of the image, and output them in an application. However to properly check the pixels of the image I need to acquire the dimensions to load it to a WriteableBitmap that can get me the pixel colors.

When I open a stream to the file a second time the app just hangs. Here's the code:

    private static async Task<Dictionary<Color, int>> GetColorCountsAsync(string path)
    {
        var colorCounts = new Dictionary<Color, int>();

        var absolutePath = string.Format(@"{0}\{1}",Directory.GetCurrentDirectory(),path);

        var dimension = await GetBitmapDimensions(absolutePath); //Method below - opens via StorageFile

        var file = await StorageFile.GetFileFromPathAsync(absolutePath); //Hangs forever
        using (var stream = await file.OpenStreamForReadAsync().ConfigureAwait(false))
        {
            var pixelWidth = dimension.Width;
            var pixelHeight = dimension.Height;
            var bitmap = new WriteableBitmap(pixelWidth, pixelHeight);

            bitmap.SetSource(stream.AsRandomAccessStream());

            using (var buffer = bitmap.PixelBuffer.AsStream())
            {
                var pixels = new byte[4 * pixelWidth * pixelHeight];
                buffer.Read(pixels, 0, pixels.Length);

                for (var y = 0; y < pixelHeight; y++)
                {
                    for (var x = 0; x < pixelWidth; x++)
                    {
                        var index = ((y * pixelWidth) + x) * 4;

                        var alpha = pixels[index + 4];
                        var red = pixels[index + 2];
                        var green = pixels[index + 1];
                        var blue = pixels[index + 0];
                        var color = Color.FromArgb(alpha, red, green, blue);

                        if (!colorCounts.ContainsKey(color))
                        {
                            colorCounts.Add(color, 0);
                        }
                        colorCounts[color] = colorCounts[color] + 1;
                    }
                }
            }
        }

        return colorCounts;
    }
    private static async Task<Dimension> GetBitmapDimensions(string absolutePath)
    {
        var file = await StorageFile.GetFileFromPathAsync(absolutePath);
        var bitmapImage = new BitmapImage();
        using (var fileStream = await file.OpenAsync(FileAccessMode.Read))
        {
            bitmapImage.SetSource(fileStream);
        }

        return new Dimension { Height = bitmapImage.PixelHeight, Width = bitmapImage.PixelWidth };
    }

I can't close the bitmap image nor dispose it - what's causing the app to freeze?

C Bauer
  • 5,003
  • 4
  • 33
  • 62

1 Answers1

0

You don't need the bitmap in the correct dimensions, as SetStream() is an extension method. It just needs an object first, call it like this:

  var bitmap = new WriteableBitmap(1,1).SetSource(stream.AsRandomAccessStream());
thumbmunkeys
  • 20,606
  • 8
  • 62
  • 110