吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2254|回复: 27
收起左侧

[C&C++ 原创] 分享一个,C++的屏幕截图工具,开箱即食

[复制链接]
Chui2i 发表于 2024-3-14 14:38
开箱即食

C++的屏幕截图工具,扩展屏也可以截到里面。

截图

截图


截图

截图

[C++] 纯文本查看 复制代码
#include <windows.h>
#include <gdiplus.h>
#include <string>
#include <iostream>
#include <locale>
#include <codecvt>
#include <shellscalingapi.h>
#pragma comment (lib,"Gdiplus.lib")
#pragma comment(lib, "Shcore.lib")

using namespace Gdiplus;
using namespace std;


void SaveHBITMAPToFile(HBITMAP hBitmap, const wchar_t* filename) {
    Bitmap bitmap(hBitmap, NULL);
    CLSID bmpClsid;
    CLSIDFromString(L"{557CF400-1A04-11D3-9A73-0000F81EF32E}", &bmpClsid);
    if (bitmap.Save(filename, &bmpClsid, NULL) != Gdiplus::Status::Ok) {
        wcerr << L"Failed to save bitmap to file: " << filename << endl;
    }
    else {
        UINT width = bitmap.GetWidth();
        UINT height = bitmap.GetHeight();
    }
}

BOOL CaptureScreen(const wchar_t* filename, int x, int y, int width, int height) {
    HDC hScreenDC = GetDC(NULL);
    if (!hScreenDC) {
        return FALSE;
    }

    HDC hMemoryDC = CreateCompatibleDC(hScreenDC);
    HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC, width, height);
    HGDIOBJ oldBitmap = SelectObject(hMemoryDC, hBitmap);

    BOOL result = BitBlt(hMemoryDC, 0, 0, width, height, hScreenDC, x, y, SRCCOPY);
    if (result) {
        SaveHBITMAPToFile(hBitmap, filename);
    }

    SelectObject(hMemoryDC, oldBitmap);
    DeleteObject(hBitmap);
    DeleteDC(hMemoryDC);
    ReleaseDC(NULL, hScreenDC);

    return result;
}

BOOL CALLBACK MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM pData) {
    MONITORINFOEX mi;
    mi.cbSize = sizeof(MONITORINFOEX);
    if (!GetMonitorInfo(hMonitor, &mi)) {
        return TRUE;
    }

    if (mi.dwFlags == DISPLAY_DEVICE_MIRRORING_DRIVER) {
        return TRUE; 
    }

    static int monitorCount = 0;
    wstring path = *(wstring*)pData;
    wstring filename = path + L"\\screenshot" + to_wstring(++monitorCount) + L".bmp";

    int x = mi.rcMonitor.left;
    int y = mi.rcMonitor.top;
    int width = mi.rcMonitor.right - x;
    int height = mi.rcMonitor.bottom - y;

    if (!CaptureScreen(filename.c_str(), x, y, width, height)) {
        wcerr << L"Failed to capture screen for monitor " << monitorCount << endl;
    }

    return TRUE;
}

int main(int argc, char* argv[]) {
    if (argc != 2) {
        cout << "Usage: " << argv[0] << " <output_directory>" << endl;
        return 1;
    }

    SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);

    GdiplusStartupInput gdiplusStartupInput;
    ULONG_PTR gdiplusToken;
    GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

    wstring outputPath = wstring_convert<codecvt_utf8<wchar_t>>().from_bytes(argv[1]);
    EnumDisplayMonitors(NULL, NULL, MonitorEnumProc, (LPARAM)&outputPath);

    GdiplusShutdown(gdiplusToken);

    return 0;
}

免费评分

参与人数 3吾爱币 +8 热心值 +3 收起 理由
FengJonas + 1 热心回复!
nanaqilin + 1 + 1 最近我也在研究截图取色这方面的小工具,谢谢楼主提供思路
爱飞的猫 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

豪~豪 发表于 2024-3-14 16:26
使用AI优化了一下,不知道能不能运行
[C++] 纯文本查看 复制代码
#include <windows.h>
#include <gdiplus.h>
#include <string>
#include <iostream>
#include <locale>
#include <codecvt>
#include <shellscalingapi.h>
#include <vector>
#pragma comment (lib,"Gdiplus.lib")
#pragma comment(lib, "Shcore.lib")

using namespace Gdiplus;
using namespace std;

// 支持多种图像格式保存
class ImageSaver {
public:
    ImageSaver(const string& format) : format_(format) {}

    bool Save(Bitmap& bitmap, const wstring& filename) {
        CLSID clsid;
        Status status;

        if (format_ == "png") {
            CLSIDFromString(L"{557cf400-1a04-11d3-9a73-0000f81ef32e}", &clsid); // PNG
            status = bitmap.Save(filename.c_str(), &clsid, NULL);
        } else if (format_ == "jpg" || format_ == "jpeg") {
            EncoderParameters encoderParams;
            encoderParams.Count = 1;
            encoderParams.Parameter[0].Guid = EncoderQuality;
            encoderParams.Parameter[0].Type = EncoderParameterValueTypeLong;
            encoderParams.Parameter[0].NumberOfValues = 1;
            encoderParams.Parameter[0].Value = new LONG[1];
            encoderParams.Parameter[0].Value[0] = 80; // 设置JPG质量为80

            CLSIDFromString(L"{557cf401-1a04-11d3-9a73-0000f81ef32e}", &clsid); // JPEG
            status = bitmap.Save(filename.c_str(), &clsid, &encoderParams);
            delete[] encoderParams.Parameter[0].Value;
        } else { // 默认使用BMP格式
            status = bitmap.Save(filename.c_str(), &Bitmap::GetCodecClsid(Gdiplus::ImageFormatBmp), NULL);
        }

        if (status != Status::Ok) {
            wcerr << L"Failed to save bitmap to file (" << format_ << "): " << filename << endl;
            return false;
        }
        return true;
    }

private:
    string format_;
};

void SaveHBITMAPToFile(HBITMAP hBitmap, const wstring& filename, const string& format) {
    Bitmap bitmap(hBitmap, NULL);
    ImageSaver saver(format);
    saver.Save(bitmap, filename);
}

BOOL CaptureScreen(const wstring& filename, int x, int y, int width, int height, const string& format) {
    HDC hScreenDC = GetDC(NULL);
    if (!hScreenDC) {
        return FALSE;
    }

    HDC hMemoryDC = CreateCompatibleDC(hScreenDC);
    HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC, width, height);
    HGDIOBJ oldBitmap = SelectObject(hMemoryDC, hBitmap);

    BOOL result = BitBlt(hMemoryDC, 0, 0, width, height, hScreenDC, x, y, SRCCOPY);
    if (result) {
        SaveHBITMAPToFile(hBitmap, filename, format);
    }

    SelectObject(hMemoryDC, oldBitmap);
    DeleteObject(hBitmap);
    DeleteDC(hMemoryDC);
    ReleaseDC(NULL, hScreenDC);

    return result;
}

BOOL CALLBACK MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM pData) {
    // ... (原有代码不变)

    int x = mi.rcMonitor.left;
    int y = mi.rcMonitor.top;
    int width = mi.rcMonitor.right - x;
    int height = mi.rcMonitor.bottom - y;

    vector<wstring> args;
    wstring outputPath = *(wstring*)pData;
    args.push_back(outputPath);
    args.push_back(to_wstring(++monitorCount));
    wstring filename = outputPath + L"\\screenshot_" + to_wstring(monitorCount) + L"." + to_wstring("bmp"); // 默认为bmp格式

    // 假设命令行参数提供了图片格式
    if (argc > 2) {
        string format = argv[2];
        filename = outputPath + L"\\screenshot_" + to_wstring(monitorCount) + L"." + to_wstring(format);
    }

    if (!CaptureScreen(filename, x, y, width, height, "bmp")) { // 默认为bmp格式,根据实际情况修改
        wcerr << L"Failed to capture screen for monitor " << monitorCount << endl;
    }

    return TRUE;
}

int main(int argc, char* argv[]) {
    if (argc < 2 || argc > 3) {
        cout << "Usage: " << argv[0] << " <output_directory> [image_format: bmp/png/jpeg]" << endl;
        return 1;
    }

    // ... (原有代码不变)

    wstring outputPath = wstring_convert<codecvt_utf8<wchar_t>>().from_bytes(argv[1]);

    // 检查并设置图片格式
    string format = "bmp";
    if (argc == 3) {
        format = argv[2];
        if (format != "bmp" && format != "png" && format != "jpg" && format != "jpeg") {
            cerr << "Unsupported image format! Defaulting to bmp." << endl;
            format = "bmp";
        }
    }

    EnumDisplayMonitors(NULL, NULL, MonitorEnumProc, (LPARAM)&outputPath);

    // ... (原有代码不变)

    return 0;
}

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
爱飞的猫 + 1 + 1 热心回复!

查看全部评分

SN1t2lO 发表于 2024-3-15 09:56
Chui2i 发表于 2024-3-14 17:17
哈哈哈哈弊端,我不会告诉你我试过但是报错了哈哈哈哈哈

用CImage类,CImage类是ATL和MFC共用的一个类,其头文件为atlimage.h,主要用于图片文件的打开,显示与保存。
THEYX 发表于 2024-3-14 15:28
colvinboy 发表于 2024-3-14 15:33
感谢分享
小高168 发表于 2024-3-14 15:39
支持支持
adam0713 发表于 2024-3-14 15:56
感谢分享,正好在找。
SN1t2lO 发表于 2024-3-14 16:25
孬好加个jpg库压缩一下啊,直存bmp
zrf029 发表于 2024-3-14 16:40
还得是大佬,感谢分享
 楼主| Chui2i 发表于 2024-3-14 17:17
SN1t2lO 发表于 2024-3-14 16:25
孬好加个jpg库压缩一下啊,直存bmp

哈哈哈哈弊端,我不会告诉你我试过但是报错了哈哈哈哈哈
liweiqing 发表于 2024-3-14 21:26
感谢分享支持一下
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-12-13 02:48

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表