• 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下截取整个屏幕 和 指定句柄窗口的屏幕 - 你好阿汤哥 - 博客园

  • 相关阅读:
    懵了,面试官问我Redis怎么测,我哪知道!
    策略模式
    非零基础自学Java (老师:韩顺平) 第7章 面向对象编程(基础部分) 7.8 构造方法构造器
    worthington酶活性影响丨worthington酶的化学性质简介
    十六、Java多线程
    java计算机毕业设计基于springboot企业人事工资管理系统
    postman 发送post请求中的x-www-form-urlencoded和form-data的区别
    java计算机毕业设计校园临时用工网站MyBatis+系统+LW文档+源码+调试部署
    基于Netty实现的简单聊天服务组件
    机器学习-分类器-总结
  • 原文地址:https://blog.csdn.net/zp704393004/article/details/126796159