C# .NET Framework 3.5环境下如何按多边形区域裁剪提取图像
代码问题分析
- 坐标未做偏移转换:你传入的
points是基于原图左上角的绝对坐标,而新建的bmp1画布的坐标系原点是自身左上角(0,0),直接用原图坐标绘制会导致多边形绘制到新画布可视区域外,这就是小多边形无输出、大多边形位置偏移的核心原因。 - TextureBrush默认对齐问题:
TextureBrush默认以全局坐标系原点作为纹理对齐基准,没有和外接矩形的位置做匹配,进一步放大了偏移误差。 - 资源未正确释放:
TextureBrush、生成的Bitmap对象未做释放,在.NET Framework 3.5环境下容易触发GDI+资源泄漏,导致后续绘图异常。
适配.NET Framework 3.5的修复方案
直接用系统自带的System.Drawing类库即可实现,不需要依赖第三方组件,修正后的代码如下:
using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Imaging; using System.IO; void CropImage(Bitmap sourceBmp, Point[] polygonPoints) { // 1. 计算多边形的最小外接矩形 int minX = polygonPoints.Min(p => p.X); int minY = polygonPoints.Min(p => p.Y); int maxX = polygonPoints.Max(p => p.X); int maxY = polygonPoints.Max(p => p.Y); int rectWidth = maxX - minX + 1; int rectHeight = maxY - minY + 1; // 边界校验,避免尺寸为0报错 if (rectWidth <=0 || rectHeight <=0) return; // 2. 转换为新画布的相对坐标 Point[] offsetPoints = polygonPoints.Select(p => new Point(p.X - minX, p.Y - minY)).ToArray(); // 3. 初始化裁剪结果图,支持透明背景 using (Bitmap cropBmp = new Bitmap(rectWidth, rectHeight, PixelFormat.Format32bppArgb)) using (Graphics g = Graphics.FromImage(cropBmp)) { // 配置绘图参数,避免锯齿 g.SmoothingMode = SmoothingMode.AntiAlias; g.Clear(Color.Transparent); // 4. 设置裁剪区域为多边形,直接绘制原图对应区域 using (GraphicsPath path = new GraphicsPath()) { path.AddPolygon(offsetPoints); g.SetClip(path, CombineMode.Replace); // 把原图的外接矩形区域绘制到新画布的(0,0)位置 g.DrawImage(sourceBmp, new Rectangle(0,0,rectWidth, rectHeight), new Rectangle(minX, minY, rectWidth, rectHeight), GraphicsUnit.Pixel); } // 5. 保存结果,用Path.Combine避免路径拼接错误 string savePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "Image.png"); cropBmp.Save(savePath, ImageFormat.Png); } }
注意事项
- 项目需要添加
System.Drawing程序集引用,这个是.NET Framework 3.5默认自带的,无需额外安装 - 如果不需要透明背景,把
PixelFormat换成Format24bppRgb,g.Clear的颜色换成你需要的背景色即可 - 如果你的原始坐标包含超出原图边界的点,需要额外加坐标钳制逻辑,把X限制在
0~sourceBmp.Width-1,Y限制在0~sourceBmp.Height-1,避免绘图报错
内容的提问来源于stack exchange,提问作者로다현
相关产品推荐
相关产品推荐

