如何从矩形中获取图像?

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 分配给 TargetPicBoxImage 属性..

最后处理 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 旧的..