2009-03-06 24 views
7

¿alguien sabe de una manera suave/rápido de la eliminación de transparencia por parte de, por ejemplo, pngs/tiffs etc. y reemplazarlo con un fondo blanco?Retire la transparencia en imágenes con C#

Básicamente lo que necesito para esto es que necesito crear imágenes compatibles con PDF/A, que pueden, de acuerdo con la especificación, tener -no-transparencia (y, por lo tanto, un fondo blanco fijo está bien).

Cualquier ideas/sugerencias?

Saludos & gracias, -Jörg

Respuesta

13

Puede crear un mapa de bits del mismo tamaño que el png, dibujar un rectángulo blanco y luego dibujar la imagen sobre él.

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"); 
} 
+6

Insterad de dibujar un rectángulo, sólo podría llamar g.Clear (Color.white); – Guffa

+1

Impresionante - gracias por la respuesta rápida! Por alguna razón tuviera que especificar el ancho y la altura de la g.drawImage, también ... de lo contrario las imágenes colocadas en donde por alguna razón más pequeño que su .width originales/.height) –

0

1) Crear un mapa de bits con un fondo blanco y con el mismo tamaño que la imagen
2) se carga la imagen y la pintura en la parte superior de su mapa de bits "blanco"
3) Guarde la imagen recién creada

0

PNG tienen un canal alfa, por lo que el simple cambio de color no funcionará. Crea una imagen blanca del mismo tamaño y crea una imagen compuesta que superponga tu imagen sobre ella.

0

Agregando a la respuesta de Stormenet; recuerde envolver todos los objetos de mapa de bits y gráficos con la instrucción "using" para eliminar recursos no administrados.

0

espacios de nombres:

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

Creación de PNG o TIFF BitmapSource de archivo:

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

Funciones en el botón 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); 
      } 
     } 
    } 

Función:

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

convertir un canal para 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; 
    } 

ahorro BitmapSource a 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); 
      } 
     } 
    } 
3

usted tiene que quitar el canal alfa. De lo contrario, seguirá teniendo una imagen transparente, simplemente sin áreas transparentes.

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