В моем бэкэнд-коде хранятся изображения с альфой, чтобы поддерживать совместимость с максимально возможным количеством форматов, но когда я пытаюсь изменить размер и преобразовать в JPG (без альфы), я получаю все черные, альфа-канал не был установлен.WPF TransformedBitmap/ScaleTransform breaks alpha/is all black
// Creation
BitmapImage bmp = new BitmapImage();
bmp.BeginInit();
bmp.DecodePixelWidth = decodeWidth;
bmp.DecodePixelHeight = decodeHeight;
bmp.UriSource = new Uri(Filename);
bmp.CacheOption = BitmapCacheOption.OnLoad;
bmp.EndInit();
bmp.Freeze();
// Scaling
var scalar = new ScaleTransform(scale, scale);
var bmp = new TransformedBitmap(img, scalar);
bmp.Freeze();
// Testing
var formatted = new FormatConvertedBitmap(bmp, PixelFormats.Bgr32, null, 0);
PngBitmapEncoder png = new PngBitmapEncoder();
MemoryStream ms = new MemoryStream();
png.Frames.Add(BitmapFrame.Create(formatted);
png.Save(ms);
File.WriteAllBytes(dest, ms);
Очевидно, что весь этот код не в той же функции, но суть есть. Когда FormatConvertedBitmap
сохранен ПОСЛЕ СКОРОСТИ, он черный, если в исходном растровом изображении есть альфа. Перед масштабированием он работает так, как ожидалось. Нет черноты.
Сравнение (удалено из-за ограничения ссылок)
Вы можете видеть на картинке выше, что большая часть оригинала имеет альфа-канал, который преобразуется к черному, но только после трансформации.
Я нашел это Saving Windows.Media.Drawing with BmpBitmapEncoder black image - how to remove alpha? , и моя проблема аналогична, за исключением того, что это не просто пустые фоны. Есть детали «под» этой черноты.
TLDR Преобразование/масштабирование, по-видимому, нарушают возможность изменения форматов пикселей в WPF.
Что я хочу: Нечерное изображение. RGB под альфой определенно не черный.
Что я получил: Черное изображение, где альфа-канал оказал определенное влияние на результат.
Причина: Насколько я могу судить, это связано с изменением размера.
Я делаю что-то неправильно, или это какая-то странная ошибка?
Оригинальные ДДС
https://dl.dropboxusercontent.com/u/37301843/MASSEFFECT3.EXE_0xCFC054A8%20No%20MIPS.dds
ТЕСТ ПРОЕКТ https://dl.dropboxusercontent.com/u/37301843/StackOverflowExample.7z
Этот проект в полной мере демонстрирует мою ситуацию.
Для этого требуется Windows 8.1+ (для кодеков dds) и .NET 4.6.
Мысли процесс
/тестирования Я полагаю, что я буду добавлять некоторый контекст к тому, как я добрался до этой стадии.
1. Написал дружественный dds конвертер изображений (оригинальная цель этого инструмента на самом деле) 2. Обнаружил, что dds 'с альфа-каналами получился черным при преобразовании в jpg с использованием класса JpegBitmapEncoder.
3. По рисунку, что это была альфа-проблема.
4. Отладка с помощью сохранения изображения в разных точках показала, что изображение было в порядке, пока оно не изменилось.
5. Перед изменением размера сохраните, как работает jpg. Нет черноты.
6. После изменения размера jpg является черным во всех областях, где альфа = 0.
7. Настроенный кодировщик премультипировал альфа, так что результирующие пиксели были черными.
8. Не удалось решить, почему масштабирование будет делать такую вещь, но попытался вытеснить альфу, перейдя на Bgr32.
9. Все еще черный при преобразовании после масштабирования.
Можете ли вы загрузить изображение, демонстрирующее это поведение? Проблема в том, что области с частичной прозрачностью становятся полностью черными? – dbc
Я создал следующий очень простой тестовый пример: http://i.stack.imgur.com/ARfiC.png. Если я загружу его с помощью кода '// Creation', затем сохраните его с помощью кода' // Testing', прозрачные области станут черными - с масштабированием или без него. Можете ли вы загрузить изображение, которое становится черным только при масштабировании? – dbc
Является ли ваша проблема тем, что у вас есть PNG, который имеет полностью прозрачные пиксели, но также имеет некоторые «скрытые» данные о цвете? Вдоль линий [Изменить размер PNG-изображения без потери данных цвета из полностью прозрачных пикселей] (https://stackoverflow.com/questions/28467645)? – dbc