INT GetEncoderClsid(const WCHAR *format, CLSID *pClsid) 函数源码

本文介绍了一个用于获取GDI+编码器MIME类型的函数GetEncoderClsid,并详细展示了如何通过此函数找到特定编码器的类标识符(CLSID),支持多种常见的图像格式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

GetEncoderClsid函数来获取一个编码器的MIME (多用途网际邮件扩充协议)类型,然后返回该编码器的类标识符(CLSID)。GDI+中编码器的MIME类型如下:
image/bmp
image/jpeg
image/gif
image/tiff
image/png

#ifndef SCREEN_CAPTURER_H #define SCREEN_CAPTURER_H #include <string> #include <gdiplus.h> class ScreenCapturer { public: ScreenCapturer(); ~ScreenCapturer(); // 截图并保存为PNG bool captureToFile(const std::string& filename, int x = 0, int y = 0, int width = -1, int height = -1); // 截图并转换为十六进制字符串 std::string captureToHex(int x = 0, int y = 0, int width = -1, int height = -1); private: ULONG_PTR gdiplusToken; // 保存位图为PNG bool saveBitmapAsPng(HBITMAP hBitmap, const std::string& filename); // 获取图像编码器的CLSID bool getEncoderClsid(const WCHAR* format, CLSID* pClsid); }; #endif // SCREEN_CAPTURER_H #include "ScreenCapturer.h" #include "CommonUtils.h" #include <Windows.h> #include <fstream> #include <vector> #include <sstream> ScreenCapturer::ScreenCapturer() { Gdiplus::GdiplusStartupInput gdiplusStartupInput; Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); } ScreenCapturer::~ScreenCapturer() { Gdiplus::GdiplusShutdown(gdiplusToken); } bool ScreenCapturer::captureToFile(const std::string& filename, int x, int y, int width, int height) { // 获取屏幕尺寸 int screenWidth = GetSystemMetrics(SM_CXSCREEN); int screenHeight = GetSystemMetrics(SM_CYSCREEN); // 如果未指定尺寸,则使用全屏 if (width <= 0) width = screenWidth - x; if (height <= 0) height = screenHeight - y; // 确保区域在屏幕范围内 if (x < 0) x = 0; if (y < 0) y = 0; if (x + width > screenWidth) width = screenWidth - x; if (y + height > screenHeight) height = screenHeight - y; if (width <= 0 || height <= 0) return false; HDC hdcScreen = GetDC(NULL); HDC hdcMem = CreateCompatibleDC(hdcScreen); HBITMAP hBitmap = CreateCompatibleBitmap(hdcScreen, width, height); // 使用全局命名空间限定符避免冲突 ::SelectObject(hdcMem, hBitmap); // 截取指定区域 BitBlt(hdcMem, 0, 0, width, height, hdcScreen, x, y, SRCCOPY); // 保存为PNG bool result = saveBitmapAsPng(hBitmap, filename); // 清理资源 DeleteObject(hBitmap); DeleteDC(hdcMem); ReleaseDC(NULL, hdcScreen); return result; } std::string ScreenCapturer::captureToHex(int x, int y, int width, int height) { // 创建临时文件 char tempPath[MAX_PATH]; char tempFile[MAX_PATH]; GetTempPathA(MAX_PATH, tempPath); GetTempFileNameA(tempPath, "cap", 0, tempFile); // 截图到临时文件 if (!captureToFile(tempFile, x, y, width, height)) { return ""; } // 读取文件内容 std::ifstream file(tempFile, std::ios::binary); if (!file) { return ""; } // 获取文件大小 file.seekg(0, std::ios::end); std::streampos fileSize = file.tellg(); file.seekg(0, std::ios::beg); // 读取文件内容 std::vector<char> buffer(static_cast<size_t>(fileSize)); if (!file.read(&buffer[0], fileSize)) { return ""; } // 转换为十六进制 std::ostringstream hexStream; for (size_t i = 0; i < static_cast<size_t>(fileSize); i++) { unsigned char c = static_cast<unsigned char>(buffer[i]); hexStream << to_hex_string(c); } // 删除临时文件 DeleteFileA(tempFile); return hexStream.str(); } bool ScreenCapturer::saveBitmapAsPng(HBITMAP hBitmap, const std::string& filename) { Gdiplus::Bitmap bitmap(hBitmap, NULL); // 获取PNG编码器 CLSID pngClsid; if (!getEncoderClsid(L"image/png", &pngClsid)) { return false; } // 转换为宽字符串 std::wstring wfilename(filename.begin(), filename.end()); Gdiplus::Status status = bitmap.Save(wfilename.c_str(), &pngClsid, NULL); return status == Gdiplus::Ok; } bool ScreenCapturer::getEncoderClsid(const WCHAR* format, CLSID* pClsid) { UINT num = 0; // 编码器数量 UINT size = 0; // 编码器大小 Gdiplus::GetImageEncodersSize(&num, &size); if (size == 0) return false; Gdiplus::ImageCodecInfo* pImageCodecInfo = (Gdiplus::ImageCodecInfo*)malloc(size); if (pImageCodecInfo == NULL) return false; Gdiplus::GetImageEncoders(num, size, pImageCodecInfo); for (UINT i = 0; i < num; i++) { if (wcscmp(pImageCodecInfo[i].MimeType, format) == 0) { *pClsid = pImageCodecInfo[i].Clsid; free(pImageCodecInfo); return true; } } free(pImageCodecInfo); return false; }Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); 你这报错 提示没有成员
最新发布
08-01
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值