从两点裁剪图像(C#)
Posted
技术标签:
【中文标题】从两点裁剪图像(C#)【英文标题】:Crop image out of two points (C#) 【发布时间】:2015-10-13 13:43:24 【问题描述】:更新:
添加了更新的代码。
但由于某种原因,它仍然无法正常工作。如果坐标是位图坐标,可能是什么原因?我放在这里的第一个代码示例不能正常工作,第二个给我一个 OutOfMemoryException。
我在尝试裁剪两点之间的图像时遇到了问题。在我的项目中,我有一个图片框(名为 AP),一般的想法是用户单击两个点,程序会在这两个角之间裁剪图像。我尝试了两种方法,一种使用 Bitmap.Crop,另一种使用 Graphics.DrawImage,但两种方法似乎都因相同的原因而失败并且根本不起作用(裁剪了图像的一小部分)。
代码:
private void AP_Click(object sender, EventArgs e)
// Setting the corners
else if (mark_shape == 0)
var mouseEventArgs = e as MouseEventArgs;
if (picture_corners_set == 0)
northEast = AP.PointToClient(new Point(mouseEventArgs.X, mouseEventArgs.Y));
picture_corners_set = 1;
else if (picture_corners_set == 1)
southWest = AP.PointToClient(new Point(mouseEventArgs.X, mouseEventArgs.Y));
Rectangle imageRectangle = new Rectangle(southWest.X, northEast.Y, (northEast.X - southWest.X), (southWest.Y - northEast.Y));
var bmp = new Bitmap(imageRectangle.Width, imageRectangle.Height);
using (var gr = Graphics.FromImage(bmp))
gr.DrawImage(AP.Image, 0, 0, imageRectangle, GraphicsUnit.Pixel);
AP.Image = bmp;
enableAllButtons();
【问题讨论】:
点坐标是相对于屏幕、表单还是图片框? 到屏幕上,我想;我将它们初始化为 northEast = new Point(mouseEventArgs.X, mouseEventArgs.Y); 由于位图裁剪坐标是相对于位图的,您是否将鼠标坐标从屏幕坐标转换为客户端(图片框)坐标?Picturebox.PointToClient
将屏幕坐标转换为客户端(控制)坐标,参见msdn.microsoft.com/en-us/library/…
我会避免在构造函数中嵌套太多调用(使事情变得困难),但是是的,类似的事情。将这两个点转换为TopLeft.X/Y
和BottomRight.X/Y
。请注意,PointToScreen
采用 Point
,而不仅仅是单个 x 或 y 值。
【参考方案1】:
由于您裁剪的位图图像大小与用户选择的宽度/高度相同,我猜您希望该裁剪图像位于新位图的顶部/左侧并填充它。实际上,您是在告诉 DrawImage() 方法在同一位置绘制位图的该部分,尽管位图尺寸较小。
这样做的正确方法是在 (0, 0) 处绘制源矩形图像:
private Point pt1, pt2;
private void AP_Click(object sender, EventArgs e)
// ... obviously other code here ...
else if (mark_shape == 0) // Setting the corners
Point pt = AP.PointToClient(Cursor.Position);
if (picture_corners_set == 0)
pt1 = new Point(pt.X, pt.Y);
picture_corners_set = 1;
else if (picture_corners_set == 1)
pt2 = new Point(pt.X, pt.Y);
picture_corners_set = 0;
Rectangle imageRectangle = new Rectangle(new Point(Math.Min(pt1.X, pt2.X), Math.Min(pt1.Y, pt2.Y)), new Size(Math.Abs(pt2.X - pt1.X) + 1, Math.Abs(pt2.Y - pt1.Y) + 1));
var bmp = new Bitmap(imageRectangle.Width, imageRectangle.Height);
using (var gr = Graphics.FromImage(bmp))
gr.DrawImage(AP.Image, 0, 0, imageRectangle, GraphicsUnit.Pixel);
AP.Image = bmp;
enableAllButtons();
您可以使用其他几个重载来执行此操作,但上面的一个非常清楚地表明 imageRectangle
是在 (0, 0) 处绘制的。
【讨论】:
感谢您的回复,我已经使用 PointToClient 转换了坐标,但它仍然会占用图像的一小部分并对其进行拉伸。我注意到图像的宽度和高度实际上大于我的屏幕分辨率——这可能是个问题吗?我的电脑是1366*768,高1280,宽1832... 使用您用来设置积分的事件代码更新您的原始帖子。以上是关于从两点裁剪图像(C#)的主要内容,如果未能解决你的问题,请参考以下文章