2009-03-06 18 views
7

qualcuno conosce un modo agevole/rapido per rimuovere la trasparenza da ad es. pngs/tiffs ecc. e sostituendolo con uno sfondo bianco?Rimuovi la trasparenza nelle immagini con C#

Fondamentalmente ciò di cui ho bisogno è che devo creare immagini compatibili PDF/A, che possono, secondo le specifiche, avere la non trasparenza (e quindi uno sfondo bianco fisso va bene).

Qualche idea/suggerimento?

Acclamazioni & grazie, -Jörg

risposta

13

È possibile creare una bitmap delle stesse dimensioni del png, disegnare un rettangolo bianco e disegnare l'immagine sopra di esso.

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 di disegnare un rettangolo, è possibile chiamare g.Clear (Color.White); – Guffa

+1

Fantastico - grazie per la rapida risposta! Per qualche motivo ho dovuto specificare la larghezza e l'altezza per g.DrawImage, altrimenti ... altrimenti le foto posizionate dove per qualche motivo sono più piccole della loro larghezza originale/larghezza) –

0

1) Creare una bitmap con uno sfondo bianco e con le stesse dimensioni dell'immagine
2) si carica un'immagine e dipingerlo in cima alla vostra bitmap "bianco"
3) Salvare l'immagine appena creata

0

I PNG hanno un canale alfa, quindi la ricolorazione semplice non lo farà. Crea un'immagine bianca della stessa dimensione e crea un'immagine composita sovrapponendoti sopra l'immagine.

0

In aggiunta alla risposta di Stormenet; ricorda di avvolgere tutti gli oggetti Bitmap e Graphics con l'istruzione "using" per disporre le risorse non gestite.

0

spazi dei nomi:

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

Creazione PNG o TIFF BitmapSource da 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); 
      } 
     } 
    } 

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

Funzione:

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

conversione di un canale per 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; 
    } 

risparmio BitmapSource in 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

È necessario rimuovere il canale alfa. Altrimenti avrai ancora un'immagine trasparente, solo senza aree trasparenti.

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