c++ - 如何使用 C++ 应用程序制作屏幕截图?[•已解决•]
问题描述
我想制作一个制作屏幕截图并将其保存在位图(bmp 文件)中的程序。我有这个代码:
#include <atlsafe.h>
#include <iostream>
#include <windows.h>
#include <vector>
#include <fstream>
#include <atlimage.h>
using namespace std;
void TakeScreenShot(const std::string& path)
{
//setting to the screen shot
keybd_event(VK_SNAPSHOT, 0x45, KEYEVENTF_EXTENDEDKEY, 0);
keybd_event(VK_SNAPSHOT, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
//handler of the bitmap that save the screen shot
HBITMAP hBitmap;
//I have to give for it time to make it work
Sleep(100);
//take the screen shot
OpenClipboard(NULL);
//save the screen shot in the bitmap handler
hBitmap = (HBITMAP)GetClipboardData(CF_BITMAP);
//relese the screen shot
CloseClipboard();
std::vector<BYTE> buf;
IStream* stream = NULL;
HRESULT hr = CreateStreamOnHGlobal(0, TRUE, &stream);
CImage image;
ULARGE_INTEGER liSize;
// screenshot to jpg and save to stream
image.Attach(hBitmap);
image.Save(stream, Gdiplus::ImageFormatJPEG);
IStream_Size(stream, &liSize);
DWORD len = liSize.LowPart;
IStream_Reset(stream);
buf.resize(len);
IStream_Read(stream, &buf[0], len);
stream->Release();
// put the imapge in the file
std::fstream fi;
fi.open(path, std::fstream::binary | std::fstream::out);
fi.write(reinterpret_cast<const char*>(&buf[0]), buf.size() * sizeof(BYTE));
fi.close();
}
int main()
{
string path = "C:\\";
TakeScreenShot(path);
return 0;
}
我想说的第一件事是我第一次在 C++ 中处理 Windows 图形,这是我第一个制作屏幕截图的程序
该程序没有给我错误,但是在调试期间,我在"atlimage.h"
文件中给了我一个错误,
错误:
>Expression: hBitmap != 0
我该如何解决?我认为真正的问题是它必须将屏幕截图保存在文件中。(我认为因为在stackoverflow上写这个问题时我不小心按下了“Ctrl + V”并且stackoverflow检测到了一个图像......该程序基本上做了它必须做的事情但不是完全因为它没有将屏幕截图保存在文件中,它将屏幕截图保存在剪贴板中:/)
编辑: 我尝试使用其他代码:
#include <atlsafe.h>
#include <iostream>
#include <windows.h>
#include <vector>
#include <fstream>
#include <atlimage.h>
#include <string>
using namespace std;
void TakeScreenShot(const std::string& path, POINT a, POINT b)
{
//setting to the screen shot
keybd_event(VK_SNAPSHOT, 0x45, KEYEVENTF_EXTENDEDKEY, 0);
keybd_event(VK_SNAPSHOT, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
HDC hScreen = GetDC(NULL);
//handler of the bitmap that save the screen shot
HBITMAP hBitmap = CreateCompatibleBitmap(hScreen, abs(b.x - a.x), abs(b.y - a.y));;
//I have to give for it time to make it work
Sleep(100);
//take the screen shot
OpenClipboard(NULL);
EmptyClipboard();
//save the screen shot in the bitmap handler
SetClipboardData(CF_BITMAP, hBitmap);
//relese the screen shot
CloseClipboard();
std::vector<BYTE> buf;
IStream* stream = NULL;
HRESULT hr = CreateStreamOnHGlobal(0, TRUE, &stream);
CImage image;
ULARGE_INTEGER liSize;
// screenshot to jpg and save to stream
image.Attach(hBitmap);
image.Save(stream, Gdiplus::ImageFormatJPEG);
IStream_Size(stream, &liSize);
DWORD len = liSize.LowPart;
IStream_Reset(stream);
buf.resize(len);
IStream_Read(stream, &buf[0], len);
stream->Release();
// put the imapge in the file
std::fstream fi;
fi.open(path, std::fstream::binary | std::fstream::out);
fi.write(reinterpret_cast<const char*>(&buf[0]), buf.size() * sizeof(BYTE));
fi.close();
}
int main()
{
string path = "out.jpg";
POINT a, b;
a.x = 0;
a.y = 0;
b.x = 800;
b.y = 800;
TakeScreenShot(path,a,b);
return 0;
}
它似乎有效,它保存了文件并且没有给出任何错误。问题是 out.jpg 文件完全是黑色的:/。我认为文件保存说明中有错误。任何人都可以帮助我吗?
编辑 2: 我已经解决了问题:D 现在我有这个代码:
#include <atlsafe.h>
#include <iostream>
#include <windows.h>
#include <vector>
#include <fstream>
#include <atlimage.h>
using namespace std;
void TakeScreenShot(const std::string& path)
{
//setting to the screen shot
keybd_event(VK_SNAPSHOT, 0x45, KEYEVENTF_EXTENDEDKEY, 0);
keybd_event(VK_SNAPSHOT, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
//handler of the bitmap that save the screen shot
HBITMAP hBitmap;
//I have to give for it time to make it work in pratica guarda
Sleep(1000); //Modified
//take the screen shot
OpenClipboard(NULL);
//save the screen shot in the bitmap handler
hBitmap = (HBITMAP)GetClipboardData(CF_BITMAP);
//relese the screen shot
CloseClipboard();
std::vector<BYTE> buf;
IStream* stream = NULL;
HRESULT hr = CreateStreamOnHGlobal(0, TRUE, &stream);
CImage image;
ULARGE_INTEGER liSize;
// screenshot to jpg and save to stream
image.Attach(hBitmap);
image.Save(stream, Gdiplus::ImageFormatJPEG);
IStream_Size(stream, &liSize);
DWORD len = liSize.LowPart;
IStream_Reset(stream);
buf.resize(len);
IStream_Read(stream, &buf[0], len);
stream->Release();
// put the imapge in the file
std::fstream fi;
fi.open(path, std::fstream::binary | std::fstream::out);
fi.write(reinterpret_cast<const char*>(&buf[0]), buf.size() * sizeof(BYTE));
fi.close();
}
int main()
{
string path = "sus.jpg";
TakeScreenShot(path);
cout << "Calling TakeScreenShot function..." << endl; //added
Sleep(3000); //added
return 0;
}
我刚刚添加了 cout 的最后一部分,并将第 21 行的停止时间从 100 毫秒增加到 1000 毫秒。
享受我对这个程序的体验:)
解决方案
推荐阅读
- ios - 无法在 Swift 5 的 Mesibo 聊天集成中接收来自服务器的消息
- awk - 如何使用 awk 匹配以下两行?
- bash - 如何使用单个 shell 脚本在同一服务器上的两个不同用户上依次执行 unix 命令?
- php - 将阅读时间添加到 Wordpress
- swift - 从孩子访问 childByAutoID 密钥
- angular - firebaseUI 是否没有“让我登录”选项?
- python - 如何计算矩阵 X 中每对行 x 和矩阵 Y 中每对行的总和?
- jquery - 使用 jQuery 是在 Spring Boot 应用程序中制作基于 REST 的 crud UI 的唯一方法吗?
- r - 为什么下一个功能在 R studio 中对我不起作用
- python - 数据框行的访问索引