C#中关闭Bitmap抗锯齿后Graphics显示空白问题求助
问题分析与解决方案
核心错误点
你代码里的空白问题完全是这行代码导致的:
Bitmap finalImg = new(52, 52, AntiARemover);
这个Bitmap构造函数的用法完全错误——它不是用来基于已有Graphics复制图像的,而是创建一个与指定Graphics设备上下文关联的空白Bitmap,自然不会包含原图像的任何像素。另外你设置了SmoothingMode.None但没有执行任何绘图操作,等于白设置,完全没作用。
正确实现思路
要去除抗锯齿白边+转指定尺寸图像,正确流程是:
- 创建目标尺寸的空白Bitmap
- 基于这个Bitmap创建Graphics对象,关闭所有平滑相关的设置
- 将原图像绘制到目标Bitmap上(此时关闭平滑的设置才会生效)
- 处理颜色替换(注意调整顺序,要先处理再存剪贴板)
- 将最终图像存入剪贴板
修正后的代码
public PicGen(PictureBox pictureBox) { Clipboard.Clear(); // 获取原图像并按PictureBox尺寸初始化 Bitmap firstImage = new Bitmap(pictureBox.Image, pictureBox.Width, pictureBox.Height); // 创建目标尺寸的空白Bitmap(52x52) Bitmap finalImg = new Bitmap(52, 52); using (Graphics g = Graphics.FromImage(finalImg)) { // 关闭所有平滑相关设置,避免产生抗锯齿白边 g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None; g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor; g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.None; g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighSpeed; // 将原图像绘制到目标Bitmap上 g.DrawImage(firstImage, new Rectangle(0, 0, 52, 52)); } // 替换背景色(注意先处理再存剪贴板) Color backColorBottom = finalImg.GetPixel(0, 0); finalImg.ReplaceColor(backColorBottom, Color.FromArgb(54, 57, 63)); // 将处理后的图像存入剪贴板 Clipboard.SetImage(finalImg); // 记得释放Bitmap资源,避免内存泄漏 firstImage.Dispose(); finalImg.Dispose(); }
额外改进建议
- 替换颜色的性能优化:
GetPixel和自定义的ReplaceColor方法性能很差,尤其是图像较大时。建议用LockBits直接操作像素内存,能大幅提升速度。 - 资源释放:所有继承自
IDisposable的对象(比如Bitmap、Graphics)都要用using语句或者手动调用Dispose()释放,避免内存泄漏。 - 白边处理补充:如果仍然有残留白边,可能是原图像本身的半透明像素导致,可以在绘制前给目标Bitmap填充背景色(比如你要替换的深色),再绘制原图像时设置
CompositingMode为SourceCopy,覆盖半透明区域。
内容的提问来源于stack exchange,提问作者Ahmed Sherif
相关产品推荐
相关产品推荐

