如何从矩形中获取图像?
How to get an image from a rectangle?
我正在制作一个裁剪图像的程序。我有两个 PictureBoxes
和一个名为 'crop' 的按钮。一个图片框包含一个图像,当我在其中 select 一个矩形并按 'Crop' 时,selected 区域出现在另一个图片框中;所以当我按下作物时,程序正在运行。问题是:如何将裁剪区域的图像放入图片框图像中?
Rectangle rectCropArea;
Image srcImage = null;
TargetPicBox.Refresh();
//Prepare a new Bitmap on which the cropped image will be drawn
Bitmap sourceBitmap = new Bitmap(SrcPicBox.Image, SrcPicBox.Width, SrcPicBox.Height);
Graphics g = TargetPicBox.CreateGraphics();
g.DrawImage(sourceBitmap, new Rectangle(0, 0, TargetPicBox.Width, TargetPicBox.Height),
rectCropArea, GraphicsUnit.Pixel);
//Good practice to dispose the System.Drawing objects when not in use.
sourceBitmap.Dispose();
Image x = TargetPicBox.Image;
问题是 x = null 并且图片显示在图片框中,所以我怎样才能将图片从这个图片框中获取到 Image
变量中?
几个问题:
- 首先也是最重要的一点:您对
PictureBox.Image
(一个 属性)和您与 PictureBox
关联的 Graphics
之间的关系感到困惑 表面。
您从 Control.CreateGraphics
获得的 Graphics
对象只能绘制到控件的表面;通常不是你想要的;即使你这样做了,你通常也想在 Paint
事件中使用 e.Graphics
..
因此,虽然您的代码 似乎 可以工作,但它只会在表面上绘制非持久性像素。 Minimize/maximize 你会明白非持久化意味着什么..!
要更改 Bitmap
bmp,您需要将其与 Grahics
对象相关联,如下所示:
Graphics g = Graphics.FromImage(bmp);
现在可以画进去了:
g.DrawImage(sourceBitmap, targetArea, sourceArea, GraphicsUnit.Pixel);
之后,您可以将 Bitmap
分配给 TargetPicBox
的 Image
属性..
最后处理 Graphics
,或者更好,将其放入 using
子句..
我假设您已经设法给 rectCropArea
有意义的值。
另请注意,您复制源位图的方式有一个错误:如果您想要完整图像,请使用its Size
( *), 而不是 PictureBox
!!
而不是创建一个目标矩形,同样的错误,只需使用 TargetPicBox.ClientRectangle
!
这是裁剪按钮的示例代码:
// a Rectangle for testing
Rectangle rectCropArea = new Rectangle(22,22,55,99);
// see the note below about the aspect ratios of the two rectangles!!
Rectangle targetRect = TargetPicBox.ClientRectangle;
Bitmap targetBitmap = new Bitmap(targetRect.Width, targetRect.Height);
using (Bitmap sourceBitmap = new Bitmap(SrcPicBox.Image,
SrcPicBox.Image.Width, SrcPicBox.Image.Height) )
using (Graphics g = Graphics.FromImage(targetBitmap))
g.DrawImage(sourceBitmap, targetRect, rectCropArea, GraphicsUnit.Pixel);
if (TargetPicBox.Image != null) TargetPicBox.Dispose();
TargetPicBox.Image = targetBitmap;
- 当然你应该在适当的鼠标事件中准备好矩形!
- 在这里您要决定结果的纵横比;您可能不想扭曲结果!所以你需要决定是裁剪源裁剪矩形还是扩大目标矩形..!
- 除非您确定 dpi 分辨率,否则您应该使用 SetResolution 来确保新图像具有相同的分辨率!
请注意,由于我将 targetBitmap
分配给 TargetPicBox.Image
,所以我必须 而不是 处理掉它!相反,在分配新的 Image
之前,我首先 Dispose
旧的..
我正在制作一个裁剪图像的程序。我有两个 PictureBoxes
和一个名为 'crop' 的按钮。一个图片框包含一个图像,当我在其中 select 一个矩形并按 'Crop' 时,selected 区域出现在另一个图片框中;所以当我按下作物时,程序正在运行。问题是:如何将裁剪区域的图像放入图片框图像中?
Rectangle rectCropArea;
Image srcImage = null;
TargetPicBox.Refresh();
//Prepare a new Bitmap on which the cropped image will be drawn
Bitmap sourceBitmap = new Bitmap(SrcPicBox.Image, SrcPicBox.Width, SrcPicBox.Height);
Graphics g = TargetPicBox.CreateGraphics();
g.DrawImage(sourceBitmap, new Rectangle(0, 0, TargetPicBox.Width, TargetPicBox.Height),
rectCropArea, GraphicsUnit.Pixel);
//Good practice to dispose the System.Drawing objects when not in use.
sourceBitmap.Dispose();
Image x = TargetPicBox.Image;
问题是 x = null 并且图片显示在图片框中,所以我怎样才能将图片从这个图片框中获取到 Image
变量中?
几个问题:
- 首先也是最重要的一点:您对
PictureBox.Image
(一个 属性)和您与PictureBox
关联的Graphics
之间的关系感到困惑 表面。 您从Control.CreateGraphics
获得的Graphics
对象只能绘制到控件的表面;通常不是你想要的;即使你这样做了,你通常也想在Paint
事件中使用e.Graphics
..
因此,虽然您的代码 似乎 可以工作,但它只会在表面上绘制非持久性像素。 Minimize/maximize 你会明白非持久化意味着什么..!
要更改 Bitmap
bmp,您需要将其与 Grahics
对象相关联,如下所示:
Graphics g = Graphics.FromImage(bmp);
现在可以画进去了:
g.DrawImage(sourceBitmap, targetArea, sourceArea, GraphicsUnit.Pixel);
之后,您可以将 Bitmap
分配给 TargetPicBox
的 Image
属性..
最后处理 Graphics
,或者更好,将其放入 using
子句..
我假设您已经设法给 rectCropArea
有意义的值。
另请注意,您复制源位图的方式有一个错误:如果您想要完整图像,请使用its
Size
( *), 而不是PictureBox
!!而不是创建一个目标矩形,同样的错误,只需使用
TargetPicBox.ClientRectangle
!
这是裁剪按钮的示例代码:
// a Rectangle for testing
Rectangle rectCropArea = new Rectangle(22,22,55,99);
// see the note below about the aspect ratios of the two rectangles!!
Rectangle targetRect = TargetPicBox.ClientRectangle;
Bitmap targetBitmap = new Bitmap(targetRect.Width, targetRect.Height);
using (Bitmap sourceBitmap = new Bitmap(SrcPicBox.Image,
SrcPicBox.Image.Width, SrcPicBox.Image.Height) )
using (Graphics g = Graphics.FromImage(targetBitmap))
g.DrawImage(sourceBitmap, targetRect, rectCropArea, GraphicsUnit.Pixel);
if (TargetPicBox.Image != null) TargetPicBox.Dispose();
TargetPicBox.Image = targetBitmap;
- 当然你应该在适当的鼠标事件中准备好矩形!
- 在这里您要决定结果的纵横比;您可能不想扭曲结果!所以你需要决定是裁剪源裁剪矩形还是扩大目标矩形..!
- 除非您确定 dpi 分辨率,否则您应该使用 SetResolution 来确保新图像具有相同的分辨率!
请注意,由于我将 targetBitmap
分配给 TargetPicBox.Image
,所以我必须 而不是 处理掉它!相反,在分配新的 Image
之前,我首先 Dispose
旧的..