C++实现截屏(屏幕快照)功能(一)

        Windows系统本身就提供截图工具,所以第一时间想到Windows api是否提供了对应的能力,以下即是采用Windows api 实现的一组代码,并附上最全解释,仅供参考。

        该方法只能保存bitmap,如果需要保存其他格式图片,请参阅《C++实现截屏(屏幕快照)功能(二)》

#include "TestCaptureScreen.h"
#include <Windows.h>
using namespace std;

/*
name 截图文件的名称
desx 从源上裁剪的起始x位置
desy 从源上裁剪的起始y位置
desW 截图的宽度
desH 截图的高度
*/
void CaptureScreen(std::string outName,int desx, int desy, int desW, int desH)
{
    //获取屏幕的句柄
    HDC screenDC = GetDC(NULL);
    //需要注意的是对于多现实器,是从主显示器左上角为(0,0)延伸的,可以根据具体业务设置
    int screenW = desW;// GetDeviceCaps(screenDC, HORZRES);
    int screenH = desH;// GetDeviceCaps(screenDC, VERTRES);
    /*
    假如需要对屏幕进行比较多的gdi函数操作,如果每一步操作都直接对屏幕dc进行操作,
    那出现的大多数可能性都是屏幕的闪烁。
    一个很好的解决方法就是使用内存dc,将这些操作全部先在内存dc上操作,
    然后依次性在屏幕上进行操作。
    */
    HDC memDC = CreateCompatibleDC(screenDC);
    /*
    函数功能:该函数创建与指定的设备环境相关的设备兼容的位图。
    hdc:设备环境句柄。
    nWidth:指定位图的宽度,单位为像素。
    nHeight:指定位图的高度,单位为像素。
    返回值:如果函数执行成功,那么返回值是位图的句柄;
    如果函数执行失败,那么返回值为NULL。若想获取更多错误信息,请调用GetLastError。
    */
    HBITMAP hBitmap = CreateCompatibleBitmap(screenDC, screenW, screenH);
    //该函数选择一对象到指定的设备上下文环境中,该新对象替换先前的相同类型的对象。
    HBITMAP hBitmapOld = (HBITMAP)SelectObject(memDC, hBitmap);

    /*
    BOOL BitBlt(
        HDC   hdcDest,   // 目标设备上下文的句柄
        int   nXDest,    // 目标矩形的左上角 x 坐标
        int   nYDest,    // 目标矩形的左上角 y 坐标
        int   nWidth,    // 目标矩形的宽度
        int   nHeight,   // 目标矩形的高度
        HDC   hdcSrc,    // 源设备上下文的句柄
        int   nXSrc,     // 源矩形的左上角 x 坐标
        int   nYSrc,     // 源矩形的左上角 y 坐标
        DWORD dwRop      // 光栅操作码,指定如何进行位图数据的传输
    );*/
    //将指定区域的图像内存复制到位图,SRCCOPY代表复制操作枚举
    BitBlt(memDC, 0, 0, desW, desH, screenDC, 0, 70, SRCCOPY);

    //typedef struct tagBITMAPINFOHEADER {
    //    DWORD biSize;          // 结构的大小,通常为 40 字节
    //    LONG  biWidth;         // 位图的宽度(以像素为单位)
    //    LONG  biHeight;        // 位图的高度(以像素为单位)
    //    WORD  biPlanes;        // 目标设备的平面数,通常为 1
    //    WORD  biBitCount;      // 每个像素的位数,通常为 1、4、8、16、24 或 32
    //    DWORD biCompression;   // 图像的压缩方式,通常为 0(不压缩)或其他压缩方式的标志
    //    DWORD biSizeImage;     // 图像的大小,以字节为单位(可以是0,不常用)
    //    LONG  biXPelsPerMeter; // 水平分辨率,每米的像素数
    //    LONG  biYPelsPerMeter; // 垂直分辨率,每米的像素数
    //    DWORD biClrUsed;       // 位图使用的颜色索引数,0 表示使用所有可用颜色索引
    //    DWORD biClrImportant;  // 对图像显示有重要影响的颜色索引数,0 表示所有颜色都重要
    //} BITMAPINFOHEADER, * PBITMAPINFOHEADER;
    //保存文件
    BITMAPINFOHEADER bi;
    bi.biSize = sizeof(BITMAPINFOHEADER);
    bi.biWidth = desW;
    bi.biHeight = desH;
    /*
    位图的高度,以像素为单位。如果值为正,表示图像是从顶部到底部排列的;
    如果值为负,表示图像是从底部到顶部排列的。通常,正值是常见的。
    */
    bi.biPlanes = 1;//目标设备的平面数,通常为1。在绝大多数情况下,这个值是1。
    bi.biBitCount = 24;//24位彩色与32位区别在于不需要透明通道
    bi.biCompression = BI_RGB;
    /*
    常见的压缩方式包括BI_RGB(无压缩)和BI_RLE8(8位运行长度编码)。
    BI_RLE8使用这种模式保存的图片有问题
    */
    bi.biSizeImage = 0;
    bi.biXPelsPerMeter = 0;
    bi.biYPelsPerMeter = 0;
    bi.biClrUsed = 0;
    bi.biClrImportant = 0;

    DWORD dwBmpSize = ((screenW * bi.biBitCount + 31) / 32) * 4 * desH;
    HANDLE hDib = GlobalAlloc(GHND, dwBmpSize);
    char* lpbitmap = (char*)GlobalLock(hDib);
    GetDIBits(screenDC, hBitmap, 0, desH, lpbitmap, (BITMAPINFO*)&bi, DIB_RGB_COLORS);

    FILE* file = fopen(outName.c_str(), "wb");
    if (file) {
        BITMAPFILEHEADER bf;
        /*
        它对应ASCII字符"M"和"B",表示"BM",
        这是Windows位图文件的标志。在二进制表示中,它实际上是字节序列0x42 0x4D。
        */
        bf.bfType = 0x4D42;
        bf.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwBmpSize;
        bf.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

        fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, file);
        fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, file);
        fwrite(lpbitmap, dwBmpSize, 1, file);

        fclose(file);
    }

    //清理资源
    GlobalUnlock(hDib);
    GlobalFree(hDib);
    SelectObject(memDC, hBitmapOld);
    DeleteDC(memDC);
    ReleaseDC(NULL, screenDC);
    DeleteObject(hBitmap);
}

int main()
{
    CaptureScreen("测试位图.bmp", 70, 0, 1000, 1000);
    return 0;
}

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Qt是一款广泛应用于跨平台开发的图形用户界面(GUI)框架,而"C"是指其基于C++语言的特性。Qt提供了许多控件用于构建各种类型的应用程序,其中包括了截图控件。 截图控件是指在Qt应用程序中用于截取当前屏幕或指定区域的图像的一种控件。它可以帮助用户快速捕捉屏幕上的内容,并进行保存、编辑或分享。截图控件通常具有以下几个主要功能: 1. 屏幕截取:截图控件可以提供屏幕截取功能,允许用户选择某个窗口、整个屏幕或指定区域进行截图。用户可以通过鼠标拖拽或键盘操作来选择截取区域。 2. 图像编辑:截取的图像可以进行基本的编辑,例如绘制线条、箭头、文字等。这让用户可以添加标记、注释或其他图形元素来强调或说明截图中的某些内容。 3. 图像保存和分享:截图控件可以提供图像保存和分享的功能。用户可以选择将截图保存为本地文件,并可以选择保存的格式(如PNG、JPEG等)。此外,截图控件还可以提供分享功能,允许用户通过邮件、社交媒体或其他渠道分享截图。 在Qt中,实现截图控件可以使用Qt的图形类库和事件驱动机制来实现。可以通过监听鼠标事件来获取用户选择的截取区域,然后通过Qt提供的图形绘制功能绘制所选择区域的图像。最后,可以使用Qt提供的图像保存功能将截图保存到本地文件或进行分享。 总之,Qt的截图控件为用户提供了方便快捷的截屏和编辑功能,能够显著提升用户在应用程序中处理图像的效率和便利性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值