GetEncoderClsid函数,方便的获得编码器的CLSID

本文详细介绍了C++函数GetEncoderClsid的实现方式,用于获取指定格式的图像编码器CLSID。通过示例代码,展示了如何分别获取PNG、BMP、GIF、JPEG和TIFF格式的图像编码器。

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

记录该函数,方便以后查询。

int GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
{
UINT num= 0;
UINT size= 0;

ImageCodecInfo* pImageCodecInfo= NULL;

GetImageEncodersSize(&num, &size);
if(size== 0)
{
return -1;
}
pImageCodecInfo= (ImageCodecInfo*)(malloc(size));
if(pImageCodecInfo== NULL)
{
return -1;
}

GetImageEncoders(num, size, pImageCodecInfo);

for(UINT j=0; j< num; ++j)
{
if(wcscmp(pImageCodecInfo[j].MimeType, format)== 0)
{
*pClsid= pImageCodecInfo[j].Clsid;
free(pImageCodecInfo);
return j;
}
}

free(pImageCodecInfo);
return -1;
}

该函数使用方法很方便,如下面的代码就分别获得5中图像编码器的CLSID

CLSID encoderClsid

GetEncoderClsid(L"image/png", &encoderClsid); //png

GetEncoderClsid(L"image/bmp", &encoderClsid);

GetEncoderClsid(L"image/gif", &encoderClsid);

GetEncoderClsid(L"image/jpeg", &encoderClsid);

GetEncoderClsid(L"image/tiff", &encoderClsid);
#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
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值