如何在Graphics上绘制图像且避免边缘出现多余像素?
解决GDI+绘制小图像时边缘出现多余像素的问题
从你描述的情况来看:克隆得到的src_clonned.png是边缘清晰的小尺寸文字图像,但最终生成的trg.png里文字边缘出现了原本不存在的多余像素——这个问题我之前处理小图像绘制时也踩过坑!本质是GDI+默认的插值模式和像素偏移设置在处理小图像时产生的“模糊溢出”,哪怕用DrawImageUnscaled也躲不开。
问题根源
你的代码没有对Graphics对象做针对性的渲染配置,GDI+默认会启用插值和平滑处理,在绘制小尺寸图像时,会自动对边缘像素进行混合计算,导致原本透明或纯色的边缘出现多余的过渡像素。
修改后的代码
我优化了你的代码,重点添加了Graphics的精准渲染配置,同时用using语句自动释放资源(避免手动Dispose遗漏的问题):
// 加载源图并克隆目标区域 using (Image global_src_img = Image.FromFile(Application.StartupPath + "\\src.png")) using (Bitmap src_img = ((Bitmap)global_src_img).Clone(new Rectangle(160, 29, 8, 14), PixelFormat.Format32bppArgb)) { src_img.Save(Application.StartupPath + "\\src_clonned.png", ImageFormat.Png); // 创建目标位图并绘制 using (Bitmap trg_bmp = new Bitmap(100, 100)) using (Graphics gfx = Graphics.FromImage(trg_bmp)) { // 关键设置:关闭插值与平滑,确保像素精准对齐 gfx.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor; gfx.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.None; gfx.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None; // 填充黑色背景(用Brushes更简洁) gfx.FillRectangle(Brushes.Black, 0, 0, trg_bmp.Width, trg_bmp.Height); // 计算居中位置并绘制图像 int x = (trg_bmp.Width / 2) - (src_img.Width / 2); int y = (trg_bmp.Height / 2) - (src_img.Height / 2); gfx.DrawImageUnscaled(src_img, x, y); } trg_bmp.Save(Application.StartupPath + "\\trg.png", ImageFormat.Png); }
关键改动说明
InterpolationMode.NearestNeighbor:直接取最接近的原始像素值,不做任何插值计算,完全保留原图像的像素细节,彻底避免边缘混合。PixelOffsetMode.None:确保像素严格按照坐标定位绘制,不会因为自动偏移导致像素错位。SmoothingMode.None:关闭图形平滑处理,进一步杜绝边缘的模糊效果。using语句:自动释放所有实现IDisposable的对象(比如Image、Bitmap、Graphics),既避免资源泄漏,又比手动调用Dispose更可靠。
这样修改后,绘制出来的trg.png边缘就会和src_clonned.png完全一致,不会再出现多余的像素了。
内容的提问来源于stack exchange,提问作者Kosmo零
相关产品推荐
相关产品推荐

