如何在不使用“从屏幕上复制”的情况下,仅将位图捕获为图像框显示的内容?

具体来说:我需要捕获图片框实际显示的特定区域作为位图。 区域的坐标由我已覆盖在图片框顶部的控件的边界指定(但属于图片框)。 当我制作区域的“快照”时,控件被隐藏。

我尝试使用普通的屏幕捕获方法(CopyFromScreen),但你无法真正控制那里的时间。 所以它正在捕捉“插页式”状态,比如我的图片框中的照片之间的过渡。 它经常只捕获纯黑色图像(图片框的背景颜色)。

所以我尝试将显示的图像(picturebox.image属性)转换为位图。 问题是图片框很少显示图像。 它显示了一些图像的部分,根据它的尺寸模式(缩放)进行缩放和剪裁。 所以我不能只拿走我的控制坐标并将它们从整个图像中剪切掉。

所以我试着估计图像的哪个部分正在显示,并根据它来修正我的矩形。 事实certificate,我基本上是在重新创建图片框的“缩放”代码来实现这一点(使用图片框的宽高比,图像的宽高比,猜测图像当前正在发生什么级别的缩放,如果它更大或小于图片框等)。 它不漂亮。

所以:现在我需要一种只捕获当前正在图片框的客户区显示的位图的方法,包括照片和当前正在其周围显示的任何黑色“信箱”。 有人有吗?

请记住,我不能依赖使用CopyFromScreen。 它对我的目的来说不够可靠。 我想我需要一种获取图片框的方法来告诉我它正在显示的位。

这将复制并保存PictureBox当前显示的内容,包括BackgroundImage (如果有一个,如果它通过),以及属于PictureBox所有Controls ,如Labels等。还包括在Paint事件中绘制的元素。 在Paint事件之外 Paint的内容是非持久性的不会包含在内。

 using (Bitmap bmp = new Bitmap(pictureBox1.ClientSize.Width, pictureBox1.ClientSize.Height)) { pictureBox1.DrawToBitmap(bmp, pictureBox1.ClientRectangle); bmp.Save(yourfilename, ImageFormat.Png); } 

注意:在我的测试表单上, PicureBox位于AutoScroll Panel pan_PBscroll 。 PictureBox以1:1的比例显示像素,因此加载的照片比面板,表格甚至屏幕大得多。 因此,要剪切到实际可见的部分,我无法使用pictureBox1.ClientSizepictureBox1.ClientRectangle但使用了该Panel的尺寸。 这也可能适用于您。

我不确定你的时间问题。 但既然你提到CopyFromScreen这里有一些区别:

  • CopyFromScreen为每个屏幕像素制作1:1副本
  • 这包括非持久性图纸,不包括任何涵盖或隐藏的内容
  • Control.DrawToBitmap使Control将自身绘制到Bitmap上,就像它在Paint绘制自身一样
  • 这不包括任何不属于Control的内容,但包含其Controls集合的所有成员
  • 这也排除了非持久性图纸,但包括控件的完整尺寸,是否适合表格或屏幕,以及是否隐藏或覆盖。
  • 对于具有活动滚动条的控件,仅复制可见部分。 要复制所有你需要暂时调整它的大小。 然后,即使它有一千个项目,您也可以获得列表框的完整图像。

既然你正在使用PictureBox我会说看看PictureBox.Image你可以获取Bitmap对象 。

希望能帮助到你。