Сохранение индексированного BMP как PNG не сохраняет прозрачность на Mac - PullRequest
1 голос
/ 13 марта 2020

Я работаю со старым форматом игры, и они использовали индексированные растровые изображения. Для некоторых материалов с прозрачностью они используют первый индекс в палитре в качестве значения, которое установлено как невидимое. В коде я клонирую растровое изображение, устанавливаю значение этой палитры полностью прозрачным, а затем экспортирую его как PNG. Отлично работает на Windows. Но на Ма c это не так.

Вот что я делаю:

Bitmap cloneBitmap;
cloneBitmap = image.Clone(new Rectangle(0, 0, image.Width, image.Height), PixelFormat.Format8bppIndexed);

var palette = cloneBitmap.Palette;
palette.Entries[0] = Color.FromArgb(0, 0, 0, 0);
cloneBitmap.Palette = palette;

cloneBitmap.Save(filePath + fileName, ImageFormat.Png);

Это прекрасно работает на P C. Изображение выводится с прозрачностью. На Ма c у него нет прозрачности, пиксели с этим индексом просто черные.

Ответы [ 2 ]

2 голосов
/ 19 марта 2020

Я предполагаю, что вы используете стандартную библиотеку System.Drawing для обработки изображений в вашем приложении. В этой библиотеке есть множество функций - тонкие обертки вокруг Windows GDI + API . Таким образом, macOS может не иметь некоторых функций для обработки изображений.

Итак, у вас есть следующие варианты решения этой проблемы:

Установите библиотеку GDI + на Ma c

Если вы используете моно, вы можете попытаться установить библиотеки GDI +, чтобы обеспечить GDI + api для System.Drawing ( source ).

brew install mono-libgdiplus

Использовать Windows Compatibility Pack

Windows Пакет обеспечения совместимости предоставляет API, используемый. NET Framework только в Windows, для кроссплатформенных приложений, написанный на. NET Core / Standard.

См. документы для деталей.

Однако пакет Microsoft.Windows.Compatibility включает в себя множество API-интерфейсов, связанных с Windows, которые вам, вероятно, вообще не нужны. Если это так, вы можете установить только System.Drawing.Common пакет. Этот пакет является частью пакета совместимости для System.Drawing функций.

См. Полезную статью о том, как использовать System.Drawing.Common in. NET Core.

Использование другого сторонняя библиотека

Если предыдущие решения не помогли с вашей проблемой, попробуйте использовать сторонние библиотеки с открытым исходным кодом, чтобы выполнить sh вашу задачу. Они определенно будут корректно работать в macOS.

См. эту полезную статью из блога Microsoft, чтобы найти библиотеку обработки изображений для ваших целей.

1 голос
/ 20 марта 2020

Требования

  • Ввод: 256-цветная палитра (8bpp) BMP
  • Вывод: PNG с прозрачностью, области во входном изображении, которые используют Первая запись связанной палитры должна отображаться прозрачно
  • ОС: macOS и Windows

Проверка

  • Чтобы иметь В тестовом примере я создал BMP с 256-цветовой палитрой (8 б.п.) с разными цветами
  • . В середине BMP есть прямоугольная область angular, в которой используется цвет с индексом 0

Исходный код

При тестировании с использованием исходного кода, показанного в вопросе, он дает следующие результаты:

  • Windows. NET Каркас: область посередине прозрачна
  • Windows . NET Core: область посередине прозрачна
  • macOS. NET Core: область посередине черная
  • macOS Mono: область посередине черная

Этого следовало ожидать, так как ФП также отметил это в вопросе.

Обходной путь

Один способ, который работает во всех 4 средах (Windows. NET Framework,. NET Core Windows / Ma c и Mono) это вызов метода MakeTransparent с цветом первой записи.

Документация гласит:

publi c void MakeTransparent (System.Drawing.Color transparentColor);

Делает указанный цвет прозрачным для этого растрового изображения.

см. https://docs.microsoft.com/en-us/dotnet/api/system.drawing.bitmap.maketransparent?view=netcore-3.1#System_Drawing_Bitmap_MakeTransparent_System_Drawing_Color_

В коде это будет выглядеть так:

var firstColor = image.Palette.Entries[0];
image.MakeTransparent(Color.FromArgb(0, firstColor.R, firstColor.G, firstColor.B));
image.Save(filePath + fileName, ImageFormat.Png);

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

Тест

Если открыть PNG в программе редактирования изображений, можно увидеть прозрачную область в середине изображения:

resulting PNG in imaging software

...