Обновление: решение Клеменса является самым быстрым. На всякий случай оставлю вариант, который нашел:
Пытаясь создать минимальный воспроизводимый пример, как предложил Питер Дунихо в комментарии, я обнаружил, что неправильные значения прозрачности исходили от BitmapImageToBitmapConverter()
Это портило все изображение. Теперь я загружаю png прямо в растровое изображение и сканирую его, и это дает точные результаты:
Bitmap bmp = new Bitmap("icon.png");
Console.WriteLine(TransparencyPercentageInImage(bmp));
Вопрос был:
У меня есть несколько элементов управления изображениями в списке:
imagesList[index].Source = ReloadIcon(index);
Они загружают изображения из файлов «.png» следующим образом:
public BitmapImage ReloadIcon(int index)
{
var image = new BitmapImage();
image.BeginInit();
image.CacheOption = BitmapCacheOption.OnLoad;
image.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
image.UriSource = new Uri(iconPaths[index], UriKind.Absolute);
image.EndInit();
return image;
}
Затем я конвертирую их в растровые изображения с помощью этого конвертера:
private Bitmap BitmapImageToBitmapConverter(BitmapImage bitmapImage)
{
using (MemoryStream outStream = new MemoryStream())
{
BitmapEncoder enc = new BmpBitmapEncoder();
enc.Frames.Add(BitmapFrame.Create(bitmapImage));
enc.Save(outStream);
System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(outStream);
return new Bitmap(bitmap);
}
}
Чтобы позже сканировать каждый пиксель на прозрачность, используя этот код:
private double TransparencyPercentageInImage(Bitmap image)
{
double transpPercentage;
double transpPixelCount = 0;
double totalPixelCount = image.Height * image.Width;
Console.WriteLine("Total pixel count: " + totalPixelCount);
for (int y = 0; y < image.Height; ++y)
{
for (int x = 0; x < image.Width; ++x)
{
if (image.GetPixel(x, y).A == 0) //or !=255
{
transpPixelCount++;
}
}
}
transpPercentage = transpPixelCount / totalPixelCount * 100;
return transpPercentage;
}
В принципе, что мне делать, чтобы получить точный процент / количество прозрачных пикселей из растрового изображения?
Я ищу количество абсолютно прозрачных пикселей, а не полупрозрачных.
Я на самом деле не ищу скорости здесь, поэтому подходит любое решение. Я уже использую небезопасный код, так что это тоже приветствуется.
image.GetPixel
? Должен ли я по-прежнему использоватьMakeTransparent()
? Если возможно, также предоставьте мне некоторые ссылки или код для преобразования 32bpp и ваше предложение в целом. Я попробую завтра. - person Tony Steel   schedule 29.09.2019GetPixel
чертовски медленный. Лучше преобразовать изображение вWriteableBitmap
и получить прямой доступ к данным изображения. См., например. этот ответ для примера. - person dymanoid   schedule 29.09.2019transpColorValue
; вы только когда-либо добавляете к нему значения, вы никогда не используете эти значения - person Peter Duniho   schedule 29.09.2019