Использование Graphics.DrawImage() для рисования изображения с помощью прозрачности/альфа-канала

Я копирую изображение. (Мой фактический код изменяет размер изображения, но не относится к моему вопросу.) Мой код выглядит примерно так.

Image src = ...

using (Image dest = new Bitmap(width, height))
{
    Graphics graph = Graphics.FromImage(dest);
    graph.InterpolationMode = InterpolationMode.HighQualityBicubic;
    graph.DrawImage(src, 0, 0, width, height);
    dest.Save(filename, saveFormat);
}

Это, кажется, отлично работает, если src не загружается с изображения с прозрачными пленками (например, GIF) или альфа-каналом (например, PNG).

Как я могу получить DrawImage() для переноса прозрачных/альфа-каналов на новое изображение, а затем сохранить их при сохранении файла?

Ответ 1

Это довольно непонятно, там много вы не сказали. Самая большая проблема с прозрачностью заключается в том, что вы не можете ее увидеть. Вы пропустили пару шагов, вы явно не указали формат пикселей вашего нового растрового изображения, вы его вообще не инициализировали, и вы не сказали, какой формат вывода вы используете. Некоторые из них не поддерживают прозрачность. Так что сделайте версию, которая сделает ее кристально чистой. Из PNG-изображения, которое выглядит так в paint.net:

enter image description here

Используя этот код

        using (var src = new Bitmap("c:/temp/trans.png"))
        using (var bmp = new Bitmap(100, 100, PixelFormat.Format32bppPArgb)) 
        using (var gr = Graphics.FromImage(bmp)) {
            gr.Clear(Color.Blue);
            gr.DrawImage(src, new Rectangle(0, 0, bmp.Width, bmp.Height));
            bmp.Save("c:/temp/result.png", ImageFormat.Png);
        }

Создает это изображение:

enter image description here

Вы можете четко видеть синий фон, чтобы прозрачность работала.

Ответ 2

Я нашел этот поток, потому что у меня была та же проблема (т.е. DrawImage не копировал альфа-канал), но в моем случае это было просто потому, что я упустил из виду, что я использовал PixelFormat.Format32bppRgb вместо PixelFormat.Format32bppArgb. Так во многом то, что сказал Лукаш М в комментариях.