Как мне установить цвет фона прозрачного PNG (WPF)? - PullRequest
2 голосов
/ 14 февраля 2011

Я загружаю некоторые изображения (jpg, bmp, png и т. Д.), Выполняю некоторые манипуляции и сохраняю их снова как изображения jpg. Когда я сохраняю изображения в формате PNG с прозрачным фоном, они сохраняются на черном фоне, и я бы предпочел, чтобы он был белым. Есть ли способ сделать это?

Важным является то, что в продукте это процедура «без пользовательского интерфейса», поэтому у меня не так много возможностей, когда дело доходит до радикального изменения способа работы. Конечно, должно быть «установить фон = белый» или что-то?

Короткий фрагмент моего кода ...

// Load the image
var image = new BitmapImage();
image.BeginInit();        
image.CacheOption = BitmapCacheOption.None;
image.UriSource = "SomeImage.png";
image.EndInit();


// Some manipulation of the image here...
image.Shake().Twist().ThrowItAllAbout();


// Save it back out, in a different format
using (FileStream stream = new FileStream("SomeOtherFile.jpg", FileMode.Create))
{
    var encoder = new JpegBitmapEncoder();
    encoder.Frames.Add(BitmapFrame.Create((BitmapSource)image));
    encoder.Save(stream);
}

Ответы [ 2 ]

2 голосов
/ 04 июня 2014

Я пытался заменить прозрачные пиксели напрямую (с помощью WriteableBitmap CopyPixels / WritePixels), но это не будет работать с полупрозрачными пикселями (например, тени будут давать артефакты с черным контуром).

Поэтому я решилнарисовать мое изображение поверх белого прямоугольника перед сохранением.Работает просто отлично:

public static BitmapSource ReplaceTransparency(this BitmapSource bitmap, Color color)
{
    var rect = new Rect(0, 0, bitmap.PixelWidth, bitmap.PixelHeight);
    var visual = new DrawingVisual();
    var context = visual.RenderOpen();
    context.DrawRectangle(new SolidColorBrush(color), null, rect);
    context.DrawImage(bitmap, rect);
    context.Close();

    var render = new RenderTargetBitmap(bitmap.PixelWidth, bitmap.PixelHeight,
        96, 96, PixelFormats.Pbgra32);
    render.Render(visual);
    return render;
}

Использование:

var white = bitmap.ReplaceTransparency(Colors.White);
var enc = new JpegBitmapEncoder();
enc.Frames.Add(BitmapFrame.Create(white));
using (var fs = File.Create(filename))
    enc.Save(fs);
1 голос
/ 14 февраля 2011

Простого метода для этого не существует, кроме того, вы делаете некоторые ложные предположения, когда говорите, что прозрачные PNG будут сохранены с черным фоном, что не относится ко всем PNG и зависит исключительно от программы, которая использовалась для сохранение PNG.

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

Один из способов установить все полностью прозрачные пиксели на белый - это получить все пиксели в виде байтового массива, проверить альфа-канал каждого пикселя, и если он равен 0, вы установите для каждого другого канала этого пикселя значение 255.

...