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变量?
有几个问题:
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)
之后,您可以将分配Bitmap给Image..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)
请注意,既然我分配targetBitmap给我,TargetPicBox.Image我就不能处置它!相反,在分配新的之前Image,我首先分配 Dispose旧的..