我如何捕获位图只有什么图片框正在显示,而不使用“从屏幕复制”

本文关键字:从屏幕复制 复制 屏幕 显示 位图 何捕获 什么 | 更新日期: 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.ClientSizepictureBox1.ClientRectangle,而是使用该面板的尺寸。这很可能也适用于你。

我不确定你的时间问题。但既然你提到了CopyFromScreen,这里有一些不同之处:

  • CopyFromScreen对每个屏幕像素进行1:1的复制
  • 这包括非持久的图纸,不包括任何覆盖或隐藏的
  • Control.DrawToBitmap使控件将自己绘制到位图上,就像Paint
  • 中一样。
  • 排除不属于控件但包含其控件集合的所有成员的任何内容
  • 这也不包括非持久绘图,但包括控件的完整尺寸,无论它是否适合窗体或屏幕,无论它是否隐藏或覆盖。
  • 对于具有活动滚动条的控件,仅复制可见部分。要复制所有内容,您需要临时调整大小。然后你可以得到一个列表框的完整图像,即使它有1000个项目。

既然你正在使用一个PictureBox,我会说看看PictureBox。可以获取位图对象的图像。

希望能有所帮助。