2009-03-06 6 views
7

Kennt jemand einen glatten/schnellen Weg zum Entfernen von Transparenz von z. PNGs/Tiffs etc und ersetzen sie durch einen weißen Hintergrund?Entfernen Sie Transparenz in Bildern mit C#

Im Grunde, was ich dafür brauche, muss ich PDF/A-kompatible Bilder erstellen, die laut der Spezifikation keine Transparenz haben (und daher ein fester weißer Hintergrund ist in Ordnung).

Irgendwelche Ideen/Vorschläge?

Beifall & Dank, -Jörg

Antwort

13

Sie könnten ein Bitmap mit der gleichen Größe wie das PNG erstellen, ein weißes Rechteck zeichnen und dann das Bild darüber zeichnen.

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 zum Zeichnen eines Rechtecks, Sie könnten einfach g.Clear aufrufen (Color.White); – Guffa

+1

Super - danke für die schnelle Antwort! Aus irgendeinem Grund musste ich auch die Breite und Höhe für das g.DrawImage angeben ... ansonsten waren die platzierten Bilder aus irgendeinem Grund kleiner als ihre ursprüngliche .width/.height) –

0

1) Erstellen Sie eine Bitmap mit einem weißen Hintergrund und mit der gleichen Größe wie Ihr Bild
2) Sie Bild laden und malen sie auf Ihre „weiße“ Bitmap
3) Speichern Sie das neu erstellte Bild

0

PNGs haben Alpha-Kanal, so einfache Nachkorrigieren wird nicht tun. Erstellen Sie ein weißes Bild derselben Größe, und erstellen Sie ein zusammengesetztes Bild, das Ihr Bild überlagert.

0

Hinzufügen zu Stormenets Antwort; Denken Sie daran, alle Bitmap- und Graphics-Objekte mit einer "using" -Anweisung zu versehen, um nicht verwaltete Ressourcen zu entfernen.

0

Namespaces:

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

Erstellen von PNG oder TIFF Bitmap von Datei:

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

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

Funktion:

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

Umwandeln eines Kanals zu Gray8 Bitmap

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 Bitmap 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

Sie haben den Alpha-Kanal zu entfernen. Ansonsten haben Sie immer noch ein transparentes Bild - nur ohne transparente Bereiche.

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