MFC,C++ 截屏



原文链接:http://www.cnblogs.com/xiangism/archive/2012/06/21/2557901.html


以前本人用C#制作过一些小游戏的外挂,其中一步最重要的原理是截取电脑的屏幕,然后分析关键像素点的信息。现在用C++重用这些程序时,在截屏上遇到一些问题,现在终于解决了,贴出自己整理后的代码。

分为win32代码和MFC代码,如下


void Test_captrueScreenwin32()
{
    HDC hDesktopDc=CreateDC(_T("DISPLAY"), NULL, NULL, NULL);
    int width=GetDeviceCaps(hDesktopDc,HORZRES);
    int height=GetDeviceCaps(hDesktopDc,VERTRES);

    HBITMAP hMemBmp;
    HDC hMemDc;
    hMemBmp=  CreateCompatibleBitmap(hDesktopDc,width,height);
    hMemDc=CreateCompatibleDC(hDesktopDc);
    ::SelectObject(hMemDc,hMemBmp);

    BitBlt(hMemDc,0,0,width,height,hDesktopDc,0,0,SRCCOPY);  //一定得先复制到内存中去
     
    BITMAP bmp;
    ::GetObject(hMemBmp,sizeof(bmp),&bmp);   //从HBITMAP 到BITMAP
    
    BITMAPINFOHEADER m_bihScreen;
    ZeroMemory(&m_bihScreen, sizeof(BITMAPINFOHEADER));//位图信息头
    m_bihScreen.biBitCount = bmp.bmBitsPixel;//每个像素字节大小
    m_bihScreen.biCompression = BI_RGB;
    m_bihScreen.biHeight = bmp.bmHeight;//高度
    m_bihScreen.biPlanes = 1;
    m_bihScreen.biSize = sizeof(BITMAPINFOHEADER);
    m_bihScreen.biSizeImage = bmp.bmWidthBytes * bmp.bmHeight;//图像数据大小
    m_bihScreen.biWidth = bmp.bmWidth;//宽度

    byte *m_pbmScreenData = new byte[bmp.bmWidthBytes * bmp.bmHeight];
    GetDIBits(hMemDc,hMemBmp, 0, height, m_pbmScreenData,  
        (LPBITMAPINFO) &m_bihScreen, DIB_RGB_COLORS);//获取位图数据  从BITMAP到内存数据

    TwoDimesionArray<RGBQUAD> colors(width,height);
    for (int j=0;j<height;++j)
    {
        for (int i=0;i<width;++i)
        {
            byte *p=m_pbmScreenData+(height-1-j)*bmp.bmWidthBytes+i*4;
            RGBQUAD c={int(*p),int(*(p+1)),int(*(p+2))};   //这里获取每个位置上的像素
            colors.SetValue(i,j,c);
        }
    }

    ImageIO writer;
    writer.WriteBmp(colors,"D:\\z.bmp");
}


void Test_captureScreenMFC()
{
    CDC *pDesktopDC = CDC::FromHandle(::GetDC(NULL));//获取当前整个屏幕DC
    int width = pDesktopDC->GetDeviceCaps(HORZRES);
    int height = pDesktopDC->GetDeviceCaps(VERTRES);

    CBitmap    memBmp;
    CDC memDC;
    memBmp.CreateCompatibleBitmap(pDesktopDC, width, height);
    memDC.CreateCompatibleDC(pDesktopDC);
    memDC.SelectObject(&memBmp);  //将memBitmap选入内存DC

    memDC.BitBlt(0, 0, width, height, pDesktopDC, 0, 0, SRCCOPY);//复制屏幕图像到内存DC
    
    BITMAP bmp;
    memBmp.GetBitmap(&bmp); //CBitmap到BITMAP

    BITMAPINFOHEADER m_bihScreen;  
    ZeroMemory(&m_bihScreen, sizeof(BITMAPINFOHEADER));//位图信息头
    m_bihScreen.biBitCount = bmp.bmBitsPixel;//每个像素字节大小
    m_bihScreen.biCompression = BI_RGB;
    m_bihScreen.biHeight = bmp.bmHeight;//高度
    m_bihScreen.biPlanes = 1;
    m_bihScreen.biSize = sizeof(BITMAPINFOHEADER);
    m_bihScreen.biSizeImage = bmp.bmWidthBytes * bmp.bmHeight;//图像数据大小
    m_bihScreen.biWidth = bmp.bmWidth;//宽度

    byte *m_pbmScreenData = new byte[bmp.bmWidthBytes * bmp.bmHeight];
    GetDIBits(/*pDesktopDC->m_hDC*/memDC.m_hDC, (HBITMAP)memBmp.m_hObject, 0, height, m_pbmScreenData,  
        (LPBITMAPINFO) &m_bihScreen, DIB_RGB_COLORS);//获取位图数据  从BITMAP到内存数据

    TwoDimesionArray<RGBQUAD> colors(width,height);
    for (int j=0;j<height;++j)
    {
        for (int i=0;i<width;++i)
        {
            byte *p=m_pbmScreenData+(height-1-j)*bmp.bmWidthBytes+i*4;
            RGBQUAD c={int(*p),int(*(p+1)),int(*(p+2))};
            colors.SetValue(i,j,c);
        }
    }

    ImageIO writer;
    writer.WriteBmp(colors,"D:\\z.bmp");
}


GetDIBits是DDB转化为DIB的关键函数。
TwoDimesionArray<T>是自定义的模板类,封装了二维数组的相关操作。
ImageIO 是保存图片到文件的类。

通过这两段代码显示了win32和MFC对应数据类型的不同



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值