如何从矩形中获取图像?

use*_*682 9 c# system.drawing winforms

我正在制作一个裁剪图像的程序.我有两个PictureBoxes和一个名为'crop'的按钮.一个图片框包含一个图像,当我在其中选择一个矩形并按"裁剪"时,所选区域出现在另一个图片框中; 所以当我按下裁剪时程序正在运行.问题是:如何将裁剪区域的图像转换为图片框?

 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;
Run Code Online (Sandbox Code Playgroud)

问题是x = null并且图像显示在图片框中,那么如何将图像从此图片框中转换为Image变量?

TaW*_*TaW 4

有几个问题:

  • PictureBox.Image首先也是最重要的:您对(属性)和与表面关联的对象之间Graphics关系感到困惑。您从中获取的对象只能绘制到控件的表面上;通常不是你想要的;即使您这样做,您通常也希望在事件中使用..PictureBoxGraphicsControl.CreateGraphicsPainte.Graphics

因此,虽然您的代码似乎可以工作,但它仅将非持久像素绘制到表面上。最小化/最大化,你就会明白非持久意味着什么......!

要更改Bitmapbmp,您需要将其与Grahics如下对象关联:

Graphics g = Graphics.FromImage(bmp);
Run Code Online (Sandbox Code Playgroud)

现在您可以绘制它:

g.DrawImage(sourceBitmap, targetArea, sourceArea, GraphicsUnit.Pixel);
Run Code Online (Sandbox Code Playgroud)

之后,您可以将分配BitmapImage..TargetPicBox

最后处理掉Graphics,或者更好,将其放入using子句中。

我假设您已经设法给出了rectCropArea有意义的值。

  • 另请注意,复制源位图的方式有一个错误:如果您想要完整图像,请使用 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;
Run Code Online (Sandbox Code Playgroud)
  • 当然,您应该在适当的鼠标事件中准备好矩形!
  • 在这里您需要决定结果的纵横比;您可能不想扭曲结果!所以你需要决定是裁剪源裁剪矩形还是扩展目标矩形..!
  • 除非您确定 dpi 分辨率,否则应该使用 SetResolution 来确保新图像具有相同的分辨率!

请注意,既然我分配targetBitmap给我,TargetPicBox.Image我就不能处置它!相反,在分配新的之前Image,我首先分配 Dispose旧的..