我如何捕获位图只有什么图片框正在显示,而不使用“从屏幕复制”
本文关键字:从屏幕复制 复制 屏幕 显示 位图 何捕获 什么 | 更新日期: 2023-09-27 18:16:05
具体来说:我需要将图片框实际显示的特定区域捕获为位图。区域的坐标由覆盖在picturebox上的控件的边界指定(但它属于picturebox)。当我创建该区域的"快照"时,控件被隐藏。
我尝试使用正常的屏幕捕获方法(CopyFromScreen),但你不能真正控制时间。所以它捕捉的是"间隙"状态,就像我的图片框中照片之间的过渡。通常它只能捕捉纯黑色的图像(图片框的背景色)。
所以我尝试只是转换图像(picturebox。图像属性)显示为位图。这里的问题是,图片框很少完全显示图像。它正在显示图像的某些部分,根据它的大小模式(即缩放)进行缩放和剪辑。所以我不能把控制坐标作为一个整体从图像中剪切出来
所以我试着估计图像的哪一部分被显示,并在此基础上纠正我的矩形。事实证明,我基本上是重新创建了图片框的"缩放"代码来做到这一点(使用图片框的宽高比,图像的宽高比,猜测当前正在发生的缩放级别,如果它比图片框大或小,等等)。它不漂亮。
所以:现在我需要一个方法来捕获当前显示在图片框客户端区域的位图,包括照片和当前显示在它周围的任何黑色"letterboxing"。有人有吗?
记住,我不能依赖于使用CopyFromScreen。它对我的目的来说不够可靠。我想我需要一个方法让picturebox告诉我它正在显示的位
这将复制并保存PictureBox
当前显示的内容,包括BackgroundImage
(如果有的话,如果它通过)以及属于PictureBox
的所有Controls
,如Labels
等。还包括在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.ClientSize
和pictureBox1.ClientRectangle
,而是使用该面板的尺寸。这很可能也适用于你。
我不确定你的时间问题。但既然你提到了CopyFromScreen
,这里有一些不同之处:
-
CopyFromScreen
对每个屏幕像素进行1:1的复制 - 这包括非持久的图纸,不包括任何覆盖或隐藏的
-
Control.DrawToBitmap
使控件将自己绘制到位图上,就像Paint
中一样。 - 排除不属于控件但包含其控件集合的所有成员的任何内容
- 这也不包括非持久绘图,但包括控件的完整尺寸,无论它是否适合窗体或屏幕,无论它是否隐藏或覆盖。
- 对于具有活动滚动条的控件,仅复制可见部分。要复制所有内容,您需要临时调整大小。然后你可以得到一个列表框的完整图像,即使它有1000个项目。
既然你正在使用一个PictureBox,我会说看看PictureBox。可以获取位图对象的图像。
希望能有所帮助。