如何用Magick.NET/ImageMagick/System.Drawing.Common移除透明物体的纯色背景?
解决方案:移除透明物体后方纯色背景并转为单色
一、使用Magick.NET/ImageMagick实现
方法1:转为纯黑物体+透明背景(快速实现)
针对你接受单色物体的需求,可通过提取alpha通道生成蒙版,将物体区域转为纯黑,背景设为透明:
ImageMagick命令行:
magick input.png -alpha extract -threshold 50% -alpha copy -fill black -opaque white output.png
Magick.NET(C#)代码:
using ImageMagick; using (var image = new MagickImage("input.png")) { // 提取alpha通道生成二值蒙版(调整阈值可优化边缘精度) using (var alphaMask = image.Clone()) { alphaMask.Alpha(AlphaOption.Extract); alphaMask.Threshold(new Percentage(50)); // 将蒙版设为图像的alpha通道 image.Alpha(AlphaOption.Copy); image.Composite(alphaMask, CompositeOperator.CopyAlpha); // 将所有非透明区域转为纯黑 image.Opaque(MagickColors.White, MagickColors.Black); image.Write("output.png"); } }
方法2:保留灰度层次+透明背景
如果需要保留物体的灰度细节,仅移除白色背景:
ImageMagick命令行:
magick input.png -alpha on -channel RGB -level 0%,100%,1.0 black,white +channel -alpha background output.png
Magick.NET(C#)代码:
using ImageMagick; using (var image = new MagickImage("input.png")) { // 调整RGB通道对比度,将白色背景压至纯黑 image.Level(new Percentage(0), new Percentage(100), 1.0, MagickColors.Black, MagickColors.White, Channels.RGB); // 将原白色背景区域设为透明 image.Alpha(AlphaOption.Background); image.Write("output.png"); }
二、使用System.Drawing.Common实现
通过像素级处理分离背景与物体,转为单色+透明背景:
using System.Drawing; using System.Drawing.Imaging; var inputPath = "input.png"; var outputPath = "output.png"; using (var bmp = new Bitmap(inputPath)) { var data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); var bytesPerPixel = 4; var stride = data.Stride; var pixelBuffer = new byte[stride * bmp.Height]; System.Runtime.InteropServices.Marshal.Copy(data.Scan0, pixelBuffer, 0, pixelBuffer.Length); for (int y = 0; y < bmp.Height; y++) { for (int x = 0; x < bmp.Width; x++) { var index = y * stride + x * bytesPerPixel; byte b = pixelBuffer[index]; byte g = pixelBuffer[index + 1]; byte r = pixelBuffer[index + 2]; // 基于白色背景计算物体透明度:像素越白,透明度越高 int gray = (r + g + b) / 3; byte newAlpha = (byte)(255 - gray); // 将非透明区域设为纯黑,透明区域保持白色(最终会被alpha隐藏) byte newColor = newAlpha > 0 ? (byte)0 : (byte)255; pixelBuffer[index] = newColor; pixelBuffer[index + 1] = newColor; pixelBuffer[index + 2] = newColor; pixelBuffer[index + 3] = newAlpha; } } System.Runtime.InteropServices.Marshal.Copy(pixelBuffer, 0, data.Scan0, pixelBuffer.Length); bmp.UnlockBits(data); bmp.Save(outputPath, ImageFormat.Png); }
内容的提问来源于stack exchange,提问作者droopysinger
相关产品推荐
相关产品推荐

