• window屏幕录制


    头文件: main.h

    #ifndef __MAIN_H__
    #define __MAIN_H__
    #ifdef _DEBUG
    #define _AFXDLL
    #endif
    #include
    #include
    #include
    #include
    #include
    #endif

     实现:

    #include "main.h"

    void ShootScreen(const char* filename, HWND hWnd)
    {
        HDC hdc=GetDC(NULL);
        //HDC hdc = CreateDC((LPCWSTR)"DISPLAY", NULL, NULL, NULL);

    //CreateDC会失败,原因还没有找
        if (hdc == NULL)
        {
            std::cout<     }
        int32_t ScrWidth = 0, ScrHeight = 0;
        RECT rect = { 0 };
        if (hWnd == NULL)
        {
            ScrWidth = GetDeviceCaps(hdc, HORZRES);
            ScrHeight = GetDeviceCaps(hdc, VERTRES);
        }
        else
        {
            GetWindowRect(hWnd, &rect);
            ScrWidth = rect.right - rect.left;
            ScrHeight = rect.bottom - rect.top;
        }
        HDC hmdc = CreateCompatibleDC(hdc);

        HBITMAP hBmpScreen = CreateCompatibleBitmap(hdc, ScrWidth, ScrHeight);
        HBITMAP holdbmp = (HBITMAP)SelectObject(hmdc, hBmpScreen);

        BITMAP bm;
        GetObject(hBmpScreen, sizeof(bm), &bm);

        BITMAPINFOHEADER bi = { 0 };
        bi.biSize = sizeof(BITMAPINFOHEADER);
        bi.biWidth = bm.bmWidth;
        bi.biHeight = bm.bmHeight;
        bi.biPlanes = bm.bmPlanes;
        bi.biBitCount = bm.bmBitsPixel;
        bi.biCompression = BI_RGB;
        bi.biSizeImage = bm.bmHeight * bm.bmWidthBytes;// 图片的像素数据
        char *buf = new char[bi.biSizeImage];
        /*
        char* rgbBuf;
        char* yBuf;
        char* uBuf;
        char* vBuf;
        int frameWidth = bm.bmWidth;
        int frameHeight = bm.bmHeight;
        bool flip = TRUE;
        rgbBuf = new char[frameWidth * frameHeight * 3];
        yBuf = new char[frameWidth * frameHeight];
        uBuf = new char[frameWidth * frameHeight / 4];
        vBuf = new char[frameWidth * frameHeight / 4];
        //调色板判断
        RGBQUAD* pRGB = (RGBQUAD*)malloc(sizeof(RGBQUAD) * (unsigned int)pow(2, bi.biBitCount));
        //if (!MakePalette(bmpFile, File_header, Info_header, pRGB))
        //    cout << "No palettel" << endl;
        */

        BitBlt(hmdc, 0, 0, ScrWidth, ScrHeight, hdc, rect.left, rect.top, SRCCOPY);
        GetDIBits(hmdc, hBmpScreen, 0L, (DWORD)ScrHeight, buf, (LPBITMAPINFO)&bi, (DWORD)DIB_RGB_COLORS);

        BITMAPFILEHEADER bfh = { 0 };
        bfh.bfType = ((WORD)('M' << 8) | 'B');
        bfh.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + bi.biSizeImage;
        bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
        //RGB2YUV(bm.bmWidth,bm.bmHeight,);
    #if 1
        FILE *fp = fopen(filename, "wb");
        fwrite(&bfh, 1,  sizeof(BITMAPFILEHEADER), fp);
        fwrite(&bi, 1, sizeof(BITMAPINFOHEADER), fp);
        fwrite(buf, 1, bi.biSizeImage, fp);
        fflush(fp);
        fclose(fp);
        fp = NULL;
    #endif 
    #if 0
        HANDLE hFile = NULL;
        DWORD erM = 0;
        LPVOID lpMsgBuf;
        hFile = CreateFile((LPCWSTR)filename, GENERIC_WRITE, FILE_SHARE_WRITE, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
        /*erM = GetLastError();
            CString theErr;
        
        FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
            NULL,
            erM,
            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
            (LPTSTR)&lpMsgBuf,
            0, NULL);
        theErr.Format((wchar_t)"%s", lpMsgBuf);
        std::cout << lpMsgBuf << std::endl;
        */
        DWORD dwWrite;
        BOOL bFlag=WriteFile(hFile, &bfh, sizeof(BITMAPFILEHEADER), &dwWrite, NULL);
        bFlag = WriteFile(hFile, &bi, sizeof(BITMAPINFOHEADER), &dwWrite, NULL);
        bFlag = WriteFile(hFile, buf, bi.biSizeImage, &dwWrite, NULL);
        CloseHandle(hFile);
    #endif
        hBmpScreen = (HBITMAP)SelectObject(hmdc, holdbmp);
        ReleaseDC(NULL, hdc);
        if (buf)
            delete[] buf;
        buf = NULL;
    }

    int32_t main()
    {
        char name[256] = { 0 };
        for (int32_t i = 0; i < 200; ++i)
        {
            sprintf_s(name, 256, "%d.bmp", i);//G:/TestRTPRTCP/testScreen/
            printf("shooting %s\n", name);
            //ShootScreen(name, NULL);
            testyuvMain(0,NULL);
            //Sleep(1000);

        }
        return 0;
    }

    目前实测,在我自己的台式机可以达到70帧每秒

    原始的参考:C++ 在Windows下截取整个屏幕 和 指定句柄窗口的屏幕 - 你好阿汤哥 - 博客园

  • 相关阅读:
    知物由学 | 自监督学习助力内容风控效果提升
    Linux vi编辑器的使用
    pandas第五章 -变形
    「Verilog学习笔记」实现3-8译码器①
    JDK1.7和JDK1.8版本的新特性
    谈谈我写作生涯的画图技巧
    家庭实验室系列文章-如何迁移树莓派系统到更大的 SD 卡?
    力扣279题:完全平方数
    双硬盘安装双系统失败,grub-install to /dev/sd* failed, fatal error
    rtc的计时方式
  • 原文地址:https://blog.csdn.net/zp704393004/article/details/126796159