解决使用复制浏览器的屏幕截图出现黑色窗口的问题

Posted strive-sun

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了解决使用复制浏览器的屏幕截图出现黑色窗口的问题相关的知识,希望对你有一定的参考价值。

前提:使用电子应用程序,QT,WPF ...等框架制作的应用程序将响应GetDC打印黑屏GetWindowDC解决此问题的唯一方法是确保目标应用程序可见,并在目标应用程序所在的特定坐标处为桌面截图

C++代码:

#include <fstream>
#include <vector>
#include <windows.h>

int main() 
{
    //make sure process is DPI aware
    SetProcessDPIAware();

    HWND hwnd_target = FindWindowA("Notepad", NULL);
    if(!hwnd_target)
        return 0;

    //make sure target window is on top
    SetForegroundWindow(hwnd_target);
    Sleep(250);

    //get hdc of desktop
    HDC hdc = GetDC(HWND_DESKTOP);

    //copy bits from coordinates of target window
    RECT rc;
    GetWindowRect(hwnd_target, &rc);
    int w = rc.right - rc.left;
    int h = rc.bottom - rc.top;
    HDC memdc = CreateCompatibleDC(hdc);
    HBITMAP hbitmap = CreateCompatibleBitmap(hdc, w, h);
    HGDIOBJ oldbmp = SelectObject(memdc, hbitmap);
    BitBlt(memdc, 0, 0, w, h, hdc, rc.left, rc.top, SRCCOPY | CAPTUREBLT);
    SelectObject(memdc, oldbmp);
    DeleteDC(memdc);

    //restore the foreground
    SetForegroundWindow(GetConsoleWindow());

    //save to file
    BITMAPINFOHEADER bi = { sizeof(bi), w, h, 1, 32 };
    std::vector<BYTE> pixels(w * h * 4);
    GetDIBits(hdc, hbitmap, 0, h, pixels.data(), 
        (BITMAPINFO*)&bi, DIB_RGB_COLORS);

    std::ofstream fout("filename.bmp", std::ios::binary);
    BITMAPFILEHEADER hdr = { MB, 54 + bi.biSizeImage, 0, 0, 54 };
    fout.write((char*)&hdr, 14);
    fout.write((char*)&bi, 40);
    fout.write((char*)pixels.data(), pixels.size());

    DeleteObject(hbitmap);
    ReleaseDC(HWND_DESKTOP, hdc);

    return 0;
}

python代码:

import win32gui
import win32ui
import win32con
from ctypes import windll
from PIL import Image
import time
import ctypes

hwnd_target = win32gui.FindWindow(None, Calculator) #Chrome handle be used for test 

left, top, right, bot = win32gui.GetWindowRect(hwnd_target)
w = right - left
h = bot - top

win32gui.SetForegroundWindow(hwnd_target)
time.sleep(1.0)

hdesktop = win32gui.GetDesktopWindow()
hwndDC = win32gui.GetWindowDC(hdesktop)
mfcDC  = win32ui.CreateDCFromHandle(hwndDC)
saveDC = mfcDC.CreateCompatibleDC()

saveBitMap = win32ui.CreateBitmap()
saveBitMap.CreateCompatibleBitmap(mfcDC, w, h)

saveDC.SelectObject(saveBitMap)

result = saveDC.BitBlt((0, 0), (w, h), mfcDC, (left, top), win32con.SRCCOPY)

bmpinfo = saveBitMap.GetInfo()
bmpstr = saveBitMap.GetBitmapBits(True)

im = Image.frombuffer(
    RGB,
    (bmpinfo[bmWidth], bmpinfo[bmHeight]),
    bmpstr, raw, BGRX, 0, 1)

win32gui.DeleteObject(saveBitMap.GetHandle())
saveDC.DeleteDC()
mfcDC.DeleteDC()
win32gui.ReleaseDC(hdesktop, hwndDC)

if result == None:
    #PrintWindow Succeeded
    im.save("test.png")

注意:拷贝firefox浏览器的屏幕截图有点麻烦,因为firefox的窗口句柄是无窗口句柄,只能使用UI自动化来获取,具体操作我暂时也不会。

 

以上是关于解决使用复制浏览器的屏幕截图出现黑色窗口的问题的主要内容,如果未能解决你的问题,请参考以下文章

C语言 服务项进行全屏幕截图 但是截图后是黑屏怎么办?

截图功能在其他机器上不起作用

Atitit截屏功能的设计解决方案

创建一个不出现在打印屏幕中的窗口

如何解决Cocos2d Android截图黑色问题

如何以编程方式获取 android 设备屏幕截图? [复制]