使用 C# 删除图像中的透明度
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/618259/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Remove transparency in images with C#
提问by J?rg Battermann
does anyone know a smooth / fast way of removing transparency from e.g. pngs/tiffs etc and replacing it with a white background?
有没有人知道从例如 png/tiffs 等中删除透明度并将其替换为白色背景的平滑/快速方法?
Basically what I need this for is I need to create PDF/A compatible images, which may, according to the spec, have -no- transparency (and therefore a fixed white background is fine).
基本上我需要的是我需要创建 PDF/A 兼容的图像,根据规范,这些图像可能具有 -no- 透明度(因此固定的白色背景很好)。
Any ideas / suggestions?
任何想法/建议?
Cheers & thanks, -J?rg
干杯和感谢,-J?rg
采纳答案by Stormenet
You could create a bitmap the same size as the png, draw a white rectangle and then draw the image on top of it.
您可以创建一个与 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");
}
回答by Dan Bystr?m
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
1) 创建一个白色背景和与图像大小相同的位图
2) 加载图像并将其绘制在“白色”位图的顶部
3) 保存新创建的图像
回答by vartec
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.
PNG 有 alpha 通道,所以简单的重新着色是行不通的。创建相同大小的白色图像,并创建合成图像覆盖您的图像。
回答by tmorell
Adding to Stormenet's answer; remember to wrap all Bitmap and Graphics objects with "using" statement to dispose unmanaged resources.
添加到 Stormenet 的答案;请记住使用“using”语句包装所有 Bitmap 和 Graphics 对象以处理非托管资源。
回答by amyasoedov88
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:
从文件创建 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);
}
}
}
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
将通道转换为 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:
将 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);
}
}
}
回答by pr0gg3r
You have to remove the alpha channel. Otherwise you'll still have a transparent image - just without transparent areas.
您必须删除 alpha 通道。否则你仍然会有一个透明的图像——只是没有透明区域。
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;
}
}