Получить данные пикселей из изображения UWP - PullRequest
0 голосов
/ 10 декабря 2018

Я пишу простой инструмент, пользователь может выбрать изображение, и оно должно перечислить все цвета, найденные на картинке.

Теперь я сталкиваюсь с 2 основными проблемами, одна из которых заключается в том, что это медленнопотому что я перебираю все пиксели изображения.Во-вторых, я получаю неожиданные результаты.

Во-первых, код:

    public static async Task<List<ImageColor>> GetImageColorsAsync(StorageFile image)
    {
        List<ImageColor> colors = new List<ImageColor>();

        var imagestream = await image.OpenStreamForReadAsync(); // Convert image to stream
        var imageDecoder = await BitmapDecoder.CreateAsync(imagestream.AsRandomAccessStream()); // decode stream
        var imagePixelData = await imageDecoder.GetPixelDataAsync(); // get information about pixels
        var bytes = imagePixelData.DetachPixelData(); // get pixel data

        for (int x = 0; x < imageDecoder.PixelWidth; x++)
        {
            for (int y = 0; y < imageDecoder.PixelHeight; y++)
            {
                var location = (y * (int)imageDecoder.PixelWidth + x) * 3; // Navigate to corresponding coordinates
                var color = Color.FromArgb(0, bytes[location + 0], bytes[location + 1], bytes[location + 2]); // Filter Red Green Blue and convert this to Argb

                // find if color already exsists from its hex code
                string hex = color.ToString();
                var prevColor = colors.FirstOrDefault(a => a.ColorCodeHex == hex);

                if (colors.Count == 0 || prevColor == null)
                {
                    // new color
                    ImageColor imgColor = new ImageColor()
                    {
                        R = color.R,
                        G = color.G,
                        B = color.B,
                        ColorCodeHex = hex,
                        Occurence = 1
                    };

                    colors.Add(imgColor);
                }
                else
                {
                    // exsisting color
                    prevColor.Occurence++;
                }
            }
        }


        return colors;
    }

Теперь мне действительно нужно пройти через каждый пиксель?

И я протестировал эту функцию, используя черное изображение (полностью черное), и на этом рисунке я получил 4 цвета: черный, красный, зеленый и синий.

Кроме того, при тестировании с использованиемизображение, которое было просто скриншотом некоторого текста (поэтому присутствовали цвета черный, белый и, возможно, немного желтого), результат был огромным (почти 1000+ цветов), поэтому с моим методом явно что-то не так

Теперьстроки, где я нахожу location и color, не мои, я нашел их в Интернете, и я не могу убедиться, что именно так вы должны это сделать.

Любая помощь, ребята?

1 Ответ

0 голосов
/ 10 декабря 2018

Во-первых, у меня нет под рукой приложения UWP, но я думаю, что ваша проблема с корректностью заключается в том, что вы игнорируете шаг.Это число представляет собой количество байтов, которое система использует для представления строки, которое не равно 3 * width * y, но обычно больше для выравнивания данных строки в фиксированной сетке.

Во-вторых, вы действительно уверены, что у вас есть 3-канальное изображение, а не 4 (ARGB)?Четвертый канал, по крайней мере, объяснит, почему вы видите ненулевые значения на черном изображении, особенно потому, что вы видите (# ff0000, # 00ff00 и # 0000ff), поэтому вы получаете ff в местах, которые вы не ожидаете.

В-третьих, с точки зрения производительности было бы мудрым решением использовать словарь или хэш-набор вместо списка.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...