最近项目要求实现不规则裁剪功能。本来想用html5的canvas在前端实现的,但是发现有点困难,以下为C#端对图对片的处理。
为了让大家知道下面内容是否是自己想要的,我先发效果图。
原图 通过下面代码中的坐标得到的截图
好了,那就开始贴代码了
以下为一个按钮的事件,为裁剪准备图片、裁剪路径、保存路径
private void button1_Click(object sender, EventArgs e) { GraphicsPath path = new GraphicsPath(); Point[] p = { new Point(424,244), new Point(240,440), new Point(340,552), new Point(550,526), new Point(478,366), new Point(348,660), new Point(424,244) }; path.AddLines(p); OpenFileDialog openFileDialog = new OpenFileDialog(); openFileDialog.Filter = @"Bitmap文件(*.bmp)|*.bmp|Jpeg文件(*.jpg)|*.jpg|所有合适文件(*.bmp,*.jpg)|*.bmp;*.jpg"; openFileDialog.FilterIndex = 3; openFileDialog.RestoreDirectory = true; if (DialogResult.OK == openFileDialog.ShowDialog()) { Bitmap bit = (Bitmap)Bitmap.FromFile(openFileDialog.FileName, false); Bitmap newBit = null; BitmapCrop(bit, path, out newBit); newBit.Save(@"C:UsersPublicPicturesSample Pictures沙漠22.jpg"); } }
以下为裁剪的关键代码
/// <summary> /// 图片截图 /// </summary> /// <param name="bitmap">原图</param> /// <param name="path">裁剪路径</param> /// <param name="outputBitmap">输出图</param> /// <returns></returns> public static Bitmap BitmapCrop(Bitmap bitmap, GraphicsPath path, out Bitmap outputBitmap) { RectangleF rect = path.GetBounds(); int left = (int)rect.Left; int top = (int)rect.Top; int width = (int)rect.Width; int height = (int)rect.Height; Bitmap image = (Bitmap)bitmap.Clone(); outputBitmap = new Bitmap(width, height); for (int i = left; i < left + width; i++) { for (int j = top; j < top + height; j++) { //判断坐标是否在路径中 if (path.IsVisible(i, j)) { //复制原图区域的像素到输出图片 outputBitmap.SetPixel(i - left, j - top, image.GetPixel(i, j)); //设置原图这部分区域为透明 image.SetPixel(i, j, Color.FromArgb(0, image.GetPixel(i, j))); } else { outputBitmap.SetPixel(i - left, j - top, Color.FromArgb(0, 255, 255, 255)); } } } bitmap.Dispose(); return image; }
有了这个前台只需要获取用户的鼠标路径传到后台就可以。