【问题标题】:Take a screenshot of a Control截取控件的屏幕截图
【发布时间】:2021-11-14 05:54:23
【问题描述】:

我想使用以下代码截取 RichTextBox 的屏幕截图。
问题是它截取了表单的另一部分:

Dim memoryImage As Bitmap
Dim myGraphics As Graphics = Me.CreateGraphics()
Dim s As Size = RichTextBox2.Size
memoryImage = New Bitmap(s.Width, s.Height, myGraphics)

Dim memoryGraphics As Graphics = Graphics.FromImage(memoryImage)
memoryGraphics.CopyFromScreen(RichTextBox2.Bounds.X, RichTextBox2.Bounds.Y, 0, 0, s)
memoryImage.Save(audiooutputfolder & name & ".png")

【问题讨论】:

  • Winforms 还是 WPF?
  • 您可能需要将本地坐标转换为屏幕坐标。
  • 含义、边界和位置refer to the parent container(在这种情况下,可能是您的表单。)听起来好像您需要弄清楚您的表单在屏幕上的相对位置,然后调整相应的边界框的坐标。
  • 您能否使用您建议的行更正我的代码?我是初学者,不知道如何改正。

标签: vb.net winforms screenshot richtextbox


【解决方案1】:

Graphics.CopyFromScreen() 要求您指定屏幕坐标。
您可以使用Control.RectangleToScreen()Control.PointToScreen() 方法将本地坐标转换为屏幕坐标。
其他方法则相反,请参阅文档。

要以屏幕坐标计算控件的客户区,您可以使用其RectangleToScreen() 方法并传递ClientRectangle 属性的值:

Dim clientRectToScreen = [Control].RectangleToScreen([Control].ClientRectangle)

要包含非客户区(例如,控件的边框,包括滚动条,如果有的话),您需要其Bounds 的屏幕坐标。
有不同的方法可以做到这一点。一个简单的方法是让控件的父级获取它们,将子控件的边界传递给父级的RectangleToScreen() 方法。
如果你想打印一个Form,它是一个Top-Level Control,所以它没有Parent,直接使用它的Bounds:这些度量已经表达了屏幕坐标。

ControlToBitmap()方法中显示:

Private Function ControlToBitmap(ctrl As Control, clientAreaOnly As Boolean) As Bitmap
    If ctrl Is Nothing Then Return Nothing
    Dim rect As Rectangle

    If clientAreaOnly Then
        rect = ctrl.RectangleToScreen(ctrl.ClientRectangle)
    Else
        rect = If(ctrl.Parent Is Nothing, ctrl.Bounds, ctrl.Parent.RectangleToScreen(ctrl.Bounds))
    End If

    Dim img As New Bitmap(rect.Width, rect.Height)
    Using g As Graphics = Graphics.FromImage(img)
        g.CopyFromScreen(rect.Location, Point.Empty, img.Size)
    End Using
    Return img
End Function

要截取控件的屏幕截图,请调用此方法,将要打印的控件传递给位图并指定是只想要其内容(客户区)还是要包含非客户区(例如,如果要打印的控件是一个窗体,则需要包括标题和边框)。

  • 重要:使用Path.Combine()构建路径:

    Path.Combine(audiooutputfolder, $"{imageName}.png"
    

    如果字符串插值不可用($"{variable} other parts"),您可以将文件扩展名粘贴到文件名:

    Path.Combine(audiooutputfolder, imageName & ".png")
    
' Get the screenshot, client area only
Dim controlImage = ControlToBitmap(RichTextBox2, True)
' Save the image to the specified Path using the default PNG format
controlImage.Save(Path.Combine(audiooutputfolder, $"{imageName}.png"), ImageFormat.Png)
' [...] when done with the bitmap
controlImage.Dispose()

旁注:
如果您的应用不是 DpiAware,您可能会得到错误的屏幕坐标。
See these notes 关于这个。

【讨论】:

  • 感谢您的帮助。但它再次没有选择表格的正确部分。我尝试使用 drawtobitmap 但它只保存边框而不是内容。
  • 使用 bmp = New Bitmap(RichTextBox2.Width, RichTextBox2.Height) RichTextBox2.DrawToBitmap(bmp, New Rectangle(0, 0, bmp.Width, bmp.Height)) bmp.Save(audiooutputfolder & name & ".png") 结束使用
  • 如前所述,如果使用此代码没有预期的结果,那是因为您有一个非 DpiAware 应用程序,并且包含您尝试打印的窗口的当前屏幕是高 dpi 或缩放(或者您更改了代码,或者您没有使用此处发布的代码)。如果是这种情况,请阅读本文底部的注释,并让您的应用具有 DpiAware。
猜你喜欢
  • 1970-01-01
  • 2014-08-19
  • 1970-01-01
  • 1970-01-01
  • 2014-09-26
  • 2012-03-10
  • 2021-07-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多