简体   繁体   English

如何从矩形获取图像?

[英]How to get an image from a rectangle?

I'm making a program that's cropping images. 我正在制作一个裁剪图像的程序。 I have two PictureBoxes and a Button named 'crop'. 我有两个PictureBoxes和一个名为“ crop”的按钮。 One picture box contains an image and when I select a rectangle in it and press 'Crop' the selected area appears in the other picture box; 一个图片框包含一个图像,当我在其中选择一个矩形并按“裁剪”时,所选区域将出现在另一个图片框中; so the program is working when I press crop. 所以当我按裁剪时程序正在运行。 The problem is: How can I get the image from crop area into picture box Image? 问题是:如何将图像从裁切区域变成图片框图像?

 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;

The problem is that x = null and the image is showing in the picture box so how can I get the Image from this picture box into the Image variable ? 问题是x = null ,并且图像显示在图片框中,所以如何将图像从此图片框中获取到Image变量中?

A couple of issues: 几个问题:

  • First and most important: You are being confused about the relationship between PictureBox.Image (a Property) and the Graphics you associate with the PictureBox 's surface . 首先也是最重要的一点:您对PictureBox.Image (一个属性)和与PictureBoxSurface关联的Graphics之间的关系感到困惑。 The Graphics object you get from Control.CreateGraphics is only able to paint onto the surface of the control; Control.CreateGraphics获得的Graphics对象只能在控件的表面上绘制; usually not what you want; 通常不是您想要的; and even when you do, you usually want to do it in a Paint event using e.Graphics .. 即使您这样做,通常也希望使用e.Graphics ..在Paint事件中进行。

So, while your code seems to work, it only paints non-persistent pixels onto the surface. 因此,虽然您的代码似乎可以正常工作,但它只会在表面上绘制非持久像素。 Minimize/maximize and you'll see what non-persistent means..! 最小化/最大化,您将看到非持久的含义..!

To change a Bitmap bmp you need to associate it with a Grahics object like this: 要更改Bitmap bmp,您需要将其与Grahics对象关联,如下所示:

Graphics g = Graphics.FromImage(bmp);

Now you can draw into it: 现在您可以使用它:

g.DrawImage(sourceBitmap, targetArea, sourceArea, GraphicsUnit.Pixel);

After that you can assign the Bitmap to the Image Property of the TargetPicBox .. 之后,您可以将Bitmap分配给TargetPicBoxImage属性。

Finally dispose of the Graphics , or better, put it into a using clause.. 最后,处理Graphics ,或者更好的方法是将其放入using子句中。

I am assuming that you have managed to give the rectCropArea meaningful values. 我假设您已经设法为rectCropArea提供了有意义的值。

  • Also note that the way you copy the source bitmap has an error: If you want the full image, do use its Size (*), not the one of the PictureBox !! 另请注意,复制源位图的方式有一个错误:如果要获得完整图像,请使用 Size (*),而不要使用PictureBox

  • And instead of creating a target rectangle, with the same error, simply use the TargetPicBox.ClientRectangle ! 而不是创建具有相同错误的目标矩形,只需使用TargetPicBox.ClientRectangle

Here is an example code for the crop Button: 这是裁剪按钮的示例代码:

 // 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;
  • Of course you should have prepared the Rectangle in the proper mouse events! 当然,您应该在适当的鼠标事件中准备好矩形!
  • Here you would want to decide on the aspect ratio of the result; 在这里,您需要确定结果的长宽比; you probably don't want to distort the result! 您可能不想扭曲结果! So you need to decide whether to crop the source cropping rectangle or whether to expand the target rectangle..! 因此,您需要确定是裁剪源裁剪矩形还是扩展目标矩形。
  • Unless you are sure about the dpi resolution you should use SetResolution to make sure the new image has the same! 除非您对dpi的分辨率有把握,否则应使用SetResolution来确保新图像具有相同的分辨率!

Note that since I assign targetBitmap to TargetPicBox.Image I must not dipose of it! 请注意,由于我将targetBitmap分配给targetBitmapTargetPicBox.Image我一定不能丢弃它! Instead, before assigning a new Image , I first Dispose the old one.. 相反,在分配新Image之前,我首先DisposeImage

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM