Remove transparency in images with C#

前端 未结 6 870
野性不改
野性不改 2020-12-16 18:26

does anyone know a smooth / fast way of removing transparency from e.g. pngs/tiffs etc and replacing it with a white background?

Basically what I need this for is I

相关标签:
6条回答
  • 2020-12-16 18:43

    You could create a bitmap the same size as the png, draw a white rectangle and then draw the image on top of it.

    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");
    }
    
    0 讨论(0)
  • 2020-12-16 18:43

    PNGs have alpha channel, so simple recoloring won't do. Create white image of same size, and create composite image overlay your image over it.

    0 讨论(0)
  • 2020-12-16 18:49

    You have to remove the alpha channel. Otherwise you'll still have a transparent image - just without transparent areas.

    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 讨论(0)
  • 2020-12-16 18:55

    Adding to Stormenet's answer; remember to wrap all Bitmap and Graphics objects with "using" statement to dispose unmanaged resources.

    0 讨论(0)
  • 2020-12-16 18:57

    1) Create a bitmap with a white background and with the same size as your image
    2) Load you image and paint it on top of your "white" bitmap
    3) Save the newly created image

    0 讨论(0)
  • 2020-12-16 19:09

    namespaces:

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

    Creating PNG or TIFF BitmapSource from File:

    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);
                }
            }
        }
    

    Functions on Button Click:

    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);
                }
            }
        }
    

    Function:

    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;
        }
    

    Converting A channel to 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;
        }
    

    Saving BitmapSource to 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 讨论(0)
提交回复
热议问题