Убрать прозрачность в изображениях с помощью C # - PullRequest
7 голосов
/ 06 марта 2009

Кто-нибудь знает плавный / быстрый способ удаления прозрачности, например, из pngs / tiffs и т. д. и замена его белым фоном?

В основном мне это нужно для создания PDF / A-совместимых изображений, которые, согласно спецификации, могут иметь -no- прозрачность (и поэтому с фиксированным белым фоном все в порядке).

Есть идеи / предложения?

Приветствия и спасибо, -Jörg

Ответы [ 6 ]

15 голосов
/ 06 марта 2009

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

void RemTransp(string file) {
    Bitmap src = new Bitmap(file);
    Bitmap target = new Bitmap(src.Size.Width,src.Size.Height);
    Graphics g = Graphics.FromImage(target);
    g.DrawRectangle(new Pen(new SolidBrush(Color.White)), 0, 0, target.Width, target.Height);
    g.DrawImage(src, 0, 0);
    target.Save("Your target path");
}
5 голосов
/ 03 февраля 2016

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

class Program
{
    static void Main(string[] args)
    {
        //this also works for different file formats
        ReplaceTransparency(@"C:\Y\transparent.png", System.Drawing.Color.White).Save(@"C:\Y\no_transparency.png");
        ReplaceTransparency(@"C:\Y\transparent.gif", System.Drawing.Color.White).Save(@"C:\Y\no_transparency.gif");
    }

    public static System.Drawing.Bitmap ReplaceTransparency(string file, System.Drawing.Color background)
    {
        return ReplaceTransparency(System.Drawing.Image.FromFile(file), background);
    }

    public static System.Drawing.Bitmap ReplaceTransparency(System.Drawing.Image image, System.Drawing.Color background)
    {
        return ReplaceTransparency((System.Drawing.Bitmap)image, background);
    }

    public static System.Drawing.Bitmap ReplaceTransparency(System.Drawing.Bitmap bitmap, System.Drawing.Color background)
    {
        /* Important: you have to set the PixelFormat to remove the alpha channel.
         * Otherwise you'll still have a transparent image - just without transparent areas */
        var result = new System.Drawing.Bitmap(bitmap.Size.Width, bitmap.Size.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
        var g = System.Drawing.Graphics.FromImage(result);

        g.Clear(background);
        g.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceOver;
        g.DrawImage(bitmap, 0, 0);

        return result;
    }
}
0 голосов
/ 23 июля 2014

пространств имен:

using Microsoft.Win32;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using PdfSharp;
using PdfSharp.Pdf;
using PdfSharp.Drawing;

Создание растрового источника PNG или TIFF из файла:

BitmapSource BitmapSource;
private void OpenFile(Object sender, RoutedEventArgs e)
    {
        OpenFileDialog OpenFileDialog = new OpenFileDialog();
        OpenFileDialog.Filter = "PNG files (*.png)|*.png|TIFF files (*.tif)|*.tif";            

        if (OpenFileDialog.ShowDialog() == true)
        {
            try
            {
                if (OpenFileDialog.OpenFile() != null)
                {
                    String InitialPath = OpenFileDialog.FileName;                       
                    FileStream InitialFileStream = new FileStream(InitialPath, FileMode.Open, FileAccess.Read, FileShare.Read);

                    switch (OpenFileDialog.FilterIndex)
                    {
                        case 1:
                            PngBitmapDecoder PngBitmapDecoder = new PngBitmapDecoder(InitialFileStream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad);
                            BitmapSource = PngBitmapDecoder.Frames[0];
                            InitialFileStream.Close();
                            break;
                        case 2:
                            TiffBitmapDecoder TiffBitmapDecoder = new TiffBitmapDecoder(InitialFileStream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad);
                            BitmapSource = TiffBitmapDecoder.Frames[0];
                            InitialFileStream.Close();
                            break;
                    }  
                }
            }
            catch (Exception Exception)
            {
                MessageBox.Show("Error: Could not read file from disk. Original error: ", Exception.Message, MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
    }

Функции при нажатии кнопки:

private void ButtonClick(Object sender, RoutedEventArgs e)
    {
        PixelFormat PixelFormat = BitmapSource.Format;
        if (PixelFormat == PixelFormats.Bgra32)
        {
            try
            {
                BitmapSource = Bgra32ToBgra24(BitmapSource);
                //BitmapSource = Bgra32ToGray8(BitmapSource);
            }

            catch (Exception Exception)
            {
                MessageBox.Show("Error: Could not convert BitmapSource. Original error: ", Exception.Message, MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
    }

Функция:

public static BitmapSource Bgra32ToBgr24(BitmapSource BitmapSource)
    {
        Int32 PixelWidth = BitmapSource.PixelWidth;
        Int32 PixelHeight = BitmapSource.PixelHeight;
        Double DpiX = BitmapSource.DpiX;
        Double DpiY = BitmapSource.DpiY;

        PixelFormat InputPixelFormat = BitmapSource.Format;
        BitmapPalette InputPalette = BitmapSource.Palette;
        Int32 InputBitsPerPixel = BitmapSource.Format.BitsPerPixel;
        Int32 InputStride = PixelWidth * InputBitsPerPixel / 8;
        Byte[] InputPixelsArray = new Byte[InputStride * PixelHeight];
        BitmapSource.CopyPixels(InputPixelsArray, InputStride, 0);

        PixelFormat PixelFormat = PixelFormats.Bgr24;
        BitmapPalette Palette = null;
        Int32 BitsPerPixel = 24;
        Int32 Stride = PixelWidth * BitsPerPixel / 8;
        Byte[] PixelsArray = new Byte[InputStride * PixelHeight / 4 * 3]; 

        Int32 i = 0; Int32 j = 0; Int32 k = 0;
        while (i < InputPixelsArray.Length / 4)
        {
            PixelsArray[k] = InputPixelsArray[j];
            PixelsArray[k + 1] = InputPixelsArray[j + 1];
            PixelsArray[k + 2] = InputPixelsArray[j + 2];

            i = i + 1;
            j = j + 4;
            k = k + 3;
        }

        BitmapSource = BitmapSource.Create(PixelWidth, PixelHeight, DpiX, DpiY, PixelFormat, Palette, PixelsArray, Stride);
        return BitmapSource;
    }

Преобразование канала в Gray8 BitmapSource

public static BitmapSource Bgra32ToGray8(BitmapSource BitmapSource)
    {
        Int32 PixelWidth = BitmapSource.PixelWidth;
        Int32 PixelHeight = BitmapSource.PixelHeight;
        Double DpiX = BitmapSource.DpiX;
        Double DpiY = BitmapSource.DpiY;

        PixelFormat InputPixelFormat = BitmapSource.Format;
        BitmapPalette InputPalette = BitmapSource.Palette;
        Int32 InputBitsPerPixel = BitmapSource.Format.BitsPerPixel;
        Int32 InputStride = PixelWidth * InputBitsPerPixel / 8;
        Byte[] InputPixelsArray = new Byte[InputStride * PixelHeight];
        BitmapSource.CopyPixels(InputPixelsArray, InputStride, 0);

        PixelFormat PixelFormat = PixelFormats.Gray8;
        BitmapPalette Palette = null;
        Int32 BitsPerPixel = 8;
        Int32 Stride = PixelWidth * BitsPerPixel / 8;
        Byte[] A_PixelsArray = new Byte[InputStride * PixelHeight / 4];

        Int32 i = 0; Int32 j = 3;
        while (i < InputPixelsArray.Length / 4)
        {
            A_PixelsArray[i] = InputPixelsArray[j];

            i = i + 1;
            j = j + 4;
        }

        BitmapSource = BitmapSource.Create(PixelWidth, PixelHeight, DpiX, DpiY, PixelFormat, Palette, A_PixelsArray, Stride);
        return BitmapSource;
    }

Сохранение BitmapSource в PDF:

private void SaveFileAs(Object sender, RoutedEventArgs e)
    {
        SaveFileDialog SaveFileDialog = new SaveFileDialog();
        SaveFileDialog.Filter = "PDF files (*.pdf)|*.pdf";
        if (SaveFileDialog.ShowDialog() == true)
        {
            try
            {
                if (SaveFileDialog.FileName != null)
                {
                    String DestinationPath = SaveFileDialog.FileName;
                    FileStream DestinationFileStream = new FileStream(DestinationPath, FileMode.Create, FileAccess.Write, FileShare.Write);

                    switch (SaveFileDialog.FilterIndex)
                    {   
                        case 1:
                            PdfDocument PdfDocument = new PdfDocument();
                            PdfPage PdfPage = new PdfPage();
                            PdfDocument.Pages.Add(PdfPage);
                            XImage Image = XImage.FromBitmapSource(BitmapSource);
                            XGraphics XGraphic = XGraphics.FromPdfPage(PdfDocument.Pages[0]);

                            Double VerticalMargin = 20;
                            Double HorizontalMargin = 20;
                            Double Ratio = BitmapSource.Height / BitmapSource.Width;
                            Double ImageWidth = PdfPage.Width - 2 * VerticalMargin;
                            Double ImageHeight = Ratio * (PdfPage.Width - 2 * HorizontalMargin);

                            XGraphic.DrawImage(Image, VerticalMargin, HorizontalMargin, ImageWidth, ImageHeight);
                            PdfDocument.Save(DestinationFileStream);
                            PdfDocument.Close();
                            DestinationFileStream.Close();
                            break;
                    }
                }
            }
            catch (Exception Exception)
            {
                MessageBox.Show("Error: Could not write file to disk. Original error: ", Exception.Message, MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
    }
0 голосов
/ 24 мая 2012

Добавление к ответу Стормене; не забудьте обернуть все объекты Bitmap и Graphics выражением «using» для удаления неуправляемых ресурсов.

0 голосов
/ 06 марта 2009

PNG имеют альфа-канал, поэтому простое перекрашивание не подойдет. Создайте белое изображение того же размера и создайте составное изображение, наложив на него ваше изображение.

0 голосов
/ 06 марта 2009

1) Создайте растровое изображение с белым фоном и размером с изображение
2) Загрузите изображение и нарисуйте его поверх своего «белого» растрового изображения
3) Сохранить вновь созданное изображение

...