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


    前提:使用电子应用程序,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自动化来获取,具体操作我暂时也不会。

     

  • 相关阅读:
    Spring常用注解
    mybatis注解映射的简单分类
    Java框架中各层作用简述
    maven中groupId和artifactId的含义
    mybatis缓存
    防盗链的基本原理
    将部分字符串转化成JsonArray
    风螺旋线的进入
    3D转弯保护区长啥样?
    风螺旋线公切线的算法
  • 原文地址:https://www.cnblogs.com/strive-sun/p/12050030.html
Copyright © 2020-2023  润新知