C# 如何从矩形中获取图像?

C# 如何从矩形中获取图像?,c#,winforms,system.drawing,C#,Winforms,System.drawing,我正在制作一个裁剪图像的程序。我有两个图片框和一个名为“裁剪”的按钮。一个图片框包含图像,当我在其中选择一个矩形并按“裁剪”时,所选区域显示在另一个图片框中;所以当我按下crop时,程序正在运行。问题是:如何将裁剪区域的图像转换为图片框图像 Rectangle rectCropArea; Image srcImage = null; TargetPicBox.Refresh(); //Prepare a new Bitmap on which the cropped image wil

我正在制作一个裁剪图像的程序。我有两个
图片框和一个名为“裁剪”的按钮。一个图片框包含图像,当我在其中选择一个矩形并按“裁剪”时,所选区域显示在另一个图片框中;所以当我按下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;
问题是x=null,图像显示在图片框中,因此如何将图像从该图片框中获取到
image
变量中

有几个问题:

  • 首先也是最重要的一点:您对
    PictureBox.Image
    (属性)和与
    PictureBox
    曲面关联的
    图形之间的关系感到困惑。
    从
    控件获得的
    图形
    对象。CreateGraphics
    只能在控件的表面上绘制;通常不是你想要的;即使您这样做了,您通常也希望在
    Paint
    事件中使用
    e.Graphics
因此,虽然代码似乎运行正常,但它只在表面上绘制非持久性像素。最小化/最大化,您将看到非持久性意味着什么

要更改
Bitmap
bmp,需要将其与
Grahics
对象关联,如下所示:

Graphics g = Graphics.FromImage(bmp);
现在,您可以将其引入:

g.DrawImage(sourceBitmap, targetArea, sourceArea, GraphicsUnit.Pixel);
之后,您可以将
位图
分配给
TargetPicBox
图像
属性

最后处置
图形
,或者更好地使用
子句将其放入

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

  • 还请注意,复制源位图的方式有一个错误:如果您想要完整图像,请使用
    大小
    (*),而不是
    图片框中的一个

  • 与创建具有相同错误的目标矩形不同,只需使用
    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
我必须不使用它!相反,在分配新的
图像之前,我首先
处理旧图像