private static void RemoveClickEvent(PictureBox b) { var f1 = typeof(Control).GetField("EventDoubleClick", BindingFlags.Static | BindingFlags.NonPublic); var obj = f1?.GetValue(b); var pi = b.GetType().GetProperty("Events", BindingFlags.NonPublic | BindingFlags.Instance); var list = (EventHandlerList)pi.GetValue(b, null); list.RemoveHandler(obj, list[obj]); }
/// <summary> /// 根据给定的图像及起点坐标和终点坐标截取图像,并储存,返回截取后的图像路径 /// </summary> /// <param name="picBox">存放被截图像的PictureBox</param> /// <param name="picName">图像路径</param> /// <param name="start">起点</param> /// <param name="end">终点,起点必须在终点上方</param> /// <returns>返回截取后的图像路径</retu public static string picCutFunction(PictureBox picBox, Bitmap pic, Point start, Point end) { //-------debug----- // MessageBox.Show(start.ToString() + " end:" + end.ToString()); string picName = "original"; try { //原图高 int originalPicHeight = picBox.Image.Height; //获取图片缩放后的大小 PropertyInfo rectangleProperty = picBox.GetType().GetProperty("ImageRectangle", BindingFlags.Instance | BindingFlags.NonPublic); Rectangle rectangle = (Rectangle)rectangleProperty.GetValue(picBox, null); //图片显示的宽度 int picShowWidth = rectangle.Width; int picShowHeight = rectangle.Height; //图片左边或者上边空白的宽度 int picLeftWidth = (picShowWidth == picBox.Width) ? 0 : (picBox.Width - picShowWidth) / 2; int picTopHeight = (picShowHeight == picBox.Height) ? 0 : (picBox.Height - picShowHeight) / 2; //图片的缩放比例 double rate = (double)picShowHeight / (double)originalPicHeight; //将显示坐标转换为原图坐标 start.X = Convert.ToInt32((double)(start.X - picLeftWidth) / rate); start.Y = Convert.ToInt32((double)(start.Y - picTopHeight) / rate); end.X = Convert.ToInt32((double)(end.X - picLeftWidth) / rate); end.Y = Convert.ToInt32((double)(end.Y - picTopHeight) / rate); if (start.X < end.X && start.Y < end.Y) { int xa = start.X; int xb = end.X; int ya = start.Y; int yb = end.Y; Rectangle rec = new Rectangle(0, 0, pic.Width, pic.Height); BitmapData bd = pic.LockBits(rec, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); IntPtr ptr = bd.Scan0; int bytes = bd.Stride * bd.Height; byte[] rgbvalues = new byte[bytes]; System.Runtime.InteropServices.Marshal.Copy(ptr, rgbvalues, 0, bytes); int w; int h; w = xb - xa; h = yb - ya; Bitmap pic1 = new Bitmap(w, h);// (Application.StartupPath + @"\11.jpg"); Rectangle rec6 = new Rectangle(0, 0, w, h); BitmapData bd6 = pic1.LockBits(rec6, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); IntPtr ptr6 = bd6.Scan0; int bytes6 = bd6.Stride * bd6.Height; byte[] rgbvalues6 = new byte[bytes6]; System.Runtime.InteropServices.Marshal.Copy(ptr6, rgbvalues6, 0, bytes6); for (int i = xa; i < xb; i++) { for (int j = ya; j < yb; j++) { rgbvalues6[(j - ya) * bd6.Stride + (i - xa) * 3] = rgbvalues[j * bd.Stride + i * 3]; rgbvalues6[(j - ya) * bd6.Stride + (i - xa) * 3 + 1] = rgbvalues[j * bd.Stride + i * 3 + 1]; rgbvalues6[(j - ya) * bd6.Stride + (i - xa) * 3 + 2] = rgbvalues[j * bd.Stride + i * 3 + 2]; } } System.Runtime.InteropServices.Marshal.Copy(rgbvalues6, 0, ptr6, bytes6); pic1.UnlockBits(bd6); pic1.Save(Application.StartupPath + @"\Temp\" + Path.GetFileNameWithoutExtension(picName) + "_cuted.jpg"); //存储剪切后的图片 pic1.Dispose(); return Application.StartupPath + @"\Temp\" + Path.GetFileNameWithoutExtension(picName) + "_cuted.jpg"; } else { // MessageBox.Show("划线未完成,请重新划线!"); return ""; } } catch (Exception err) { MessageBox.Show("系统出错,请重试!---1 " + err.Message + "\n当前处理图片: " + picName); return ""; } }
private Rectangle getPictureBoxOffset(PictureBox pb) { // It seems the only way of correctly adjusting for the picturebox position after it has been resized is to access private data from the picturebox class System.Reflection.PropertyInfo pInfo = pb.GetType().GetProperty("ImageRectangle", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); return (Rectangle)pInfo.GetValue(pb, null); //return new Point(rectangle.X, rectangle.Y); }