我正在寻找最快的打印方式,我发现使用Bitblt是我更好的选择,但是,它只适用于设备上下文句柄,这对我来说意味着要从中检索位图,我必须使用多个API,包括CreateCompatibleBitmap,最终它可能需要与使用托管方式相同的时间,如graphics.CopyFromScreen(这有点慢)对我来说也消耗了大量CPU,在2.3ghz四核处理器上占7-10%......)
但是,我仍在搜索从中检索位图的更简洁方法,所以我想出了这段代码:
<DllImport("user32.dll")> _
Public Shared Function GetDC(ByVal hWnd As IntPtr) As IntPtr
End Function
<DllImport("user32.dll")> _
Public Shared Function ReleaseDC(ByVal hWnd As IntPtr, ByVal hDC As IntPtr) As Integer
End Function
<DllImport("gdi32.dll")> _
Public Shared Function BitBlt(ByVal hdcDest As IntPtr, ByVal xDest As Integer, ByVal yDest As Integer, ByVal wDest As Integer, ByVal hDest As Integer, ByVal hdcSource As IntPtr, _
ByVal xSrc As Integer, ByVal ySrc As Integer, ByVal rop As TernaryRasterOperations) As Boolean
End Function
Dim hwNd As IntPtr = Nothing
hwNd = GetDC(GetDesktopWindow)
picHandle = GetDC(Me.PictureBox1.Handle)
BitBlt(picHandle, 0, 0, PictureBox1.Width, PictureBox1.Height, hwNd, 0, 0, TernaryRasterOperations.SRCCOPY)
ReleaseDC(hwNd, picHandle)
我可以达到~30 fps ......但它有两个问题,如上所述:
即使将它显示在图片框上,因为我在上面完成了我想要的操作,它也不会调整到图片框控件的大小,即使我改变了那些&#34; 0&#34;图片框x和y坐标的值。 我进一步搜索并找到了StretchBit API,它确实拉伸,但它也降低了质量,(即使必须使用参数&#34调用SetStretchBltMode; HALFTONE&#34;所以它没有&#39; t&#34;腐败&#34;像素),它还会降低性能至少10+ fps ......
但是因为我需要将它作为位图对象,以及其他必要的API,我最终得到了几乎一半的性能(15~fps),这相当于graphics.CopyFromScreen。
所以,我问,是否有另一种方法可以在不丢失性能的情况下使用Bitblt或类似方法从屏幕上获取位图?
如果没有.Net方式,我恳请任何语言方式。
答案 0 :(得分:0)
如果您想要原始性能,则必须远离托管代码。使用C ++和Visual Studio很容易。您可以直接调用Windows API,绕过.NET运行时,应用程序的托管代码以及.NET中p / invokes的开销。
如果您熟悉C#,可以使用C#代码,将其转换为C ++(这应该很简单,需要大量工作来替换CLI)。
答案 1 :(得分:0)
Private Declare Function BitBlt Lib "GDI32" ( _
ByVal hdcDest As Integer, _
ByVal nXDest As Integer, _
ByVal nYDest As Integer, _
ByVal nWidth As Integer, _
ByVal nHeight As Integer, _
ByVal hdcSrc As Integer, _
ByVal nXSrc As Integer, _
ByVal nYSrc As Integer, _
ByVal dwRop As System.Int32) As Boolean
Declare Function QueryPerformanceCounter Lib "Kernel32" (ByRef X As Long) As Short
Declare Function QueryPerformanceFrequency Lib "Kernel32" (ByRef X As Long) As Short
Const SRCCOPY As Integer = &HCC0020
使用仅包含图片框和标签的表单。相应地设置picbox的锚点。在picbox down事件中:
Private Sub PictureBox1_MouseDown(sender As System.Object, e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
Dim Ctr1, Ctr2, Freq As Long
Dim dbl As Double
QueryPerformanceCounter(Ctr1)
Dim desktopDC As IntPtr = Nothing
Dim picboxDC As IntPtr = Nothing
desktopDC = GetDC(New IntPtr(0))
picboxDC = GetDC(PictureBox1.Handle)
BitBlt(picboxDC, 0, 0, PictureBox1.Width, PictureBox1.Height, desktopDC, 0, 0, SRCCOPY)
QueryPerformanceCounter(Ctr2)
QueryPerformanceFrequency(Freq)
dbl = (Ctr2 - Ctr1) / Freq
dbl *= 1000000
Label1.Text = dbl.ToString 'it is in microseconds
ReleaseDC(New IntPtr(0), desktopDC)
ReleaseDC(PictureBox1.Handle, picboxDC)
End Sub
最大化您的表单并点击图片框。