C++ GDI+;有标准图像编码器CLSID吗?
GDI+方法需要CLSID参数来指定要使用的编码器。文档指向获取与特定MIME类型(如image/jpeg或image/png)关联的编码器。然而,一想到复制一个半页函数只是为了支持一个单行调试辅助,在这里我将中间结果保存到磁盘上,我就犹豫了C++ GDI+;有标准图像编码器CLSID吗?,c++,winapi,gdi+,clsid,C++,Winapi,Gdi+,Clsid,GDI+方法需要CLSID参数来指定要使用的编码器。文档指向获取与特定MIME类型(如image/jpeg或image/png)关联的编码器。然而,一想到复制一个半页函数只是为了支持一个单行调试辅助,在这里我将中间结果保存到磁盘上,我就犹豫了 标准编码器不应该有一个标准CLSID列表吗?我在哪里可以找到这样的清单?我无法通过搜索Microsoft的include文件找到一个。您可能希望将ImageCodeInfo与GetImageEncodersSize()和GetImageEncoders()
标准编码器不应该有一个标准CLSID列表吗?我在哪里可以找到这样的清单?我无法通过搜索Microsoft的include文件找到一个。您可能希望将
ImageCodeInfo
与GetImageEncodersSize()
和GetImageEncoders()
一起使用
编辑:如果你明确地知道你想要什么,并且诅咒所有其他的,你可以通过做这样的事情逃脱惩罚
CLSID pngClsid;
GetEncoderClsid("image/png", &pngClsid);
image.Save("imagename.png", &pngClsid, NULL);
没有。我想他们希望编解码器列表是可扩展的,并且支持插件,但从来没有考虑过。考虑到他们已经有一段时间没有对GDI+进行任何更改,他们可能不会很快做出任何更改。基于Gdiplus::getImageEncoder的枚举,您可能不需要生成自己的硬编码列表 即:
image/bmp : {557cf400-1a04-11d3-9a73-0000f81ef32e}
image/jpeg : {557cf401-1a04-11d3-9a73-0000f81ef32e}
image/gif : {557cf402-1a04-11d3-9a73-0000f81ef32e}
image/tiff : {557cf405-1a04-11d3-9a73-0000f81ef32e}
image/png : {557cf406-1a04-11d3-9a73-0000f81ef32e}
下面是我经常在项目之间剪切和粘贴的函数,用于获取编码器的CLSID。您可以将其修改为表查找
#include <windows.h>
#include <gdiplus.h>
#include <string>
#include <vector>
HRESULT GetGdiplusEncoderClsid(const std::wstring& format, GUID* pGuid)
{
HRESULT hr = S_OK;
UINT nEncoders = 0; // number of image encoders
UINT nSize = 0; // size of the image encoder array in bytes
std::vector<BYTE> spData;
Gdiplus::ImageCodecInfo* pImageCodecInfo = NULL;
Gdiplus::Status status;
bool found = false;
if (format.empty() || !pGuid)
{
hr = E_INVALIDARG;
}
if (SUCCEEDED(hr))
{
*pGuid = GUID_NULL;
status = Gdiplus::GetImageEncodersSize(&nEncoders, &nSize);
if ((status != Gdiplus::Ok) || (nSize == 0))
{
hr = E_FAIL;
}
}
if (SUCCEEDED(hr))
{
spData.resize(nSize);
pImageCodecInfo = (Gdiplus::ImageCodecInfo*)&spData.front();
status = Gdiplus::GetImageEncoders(nEncoders, nSize, pImageCodecInfo);
if (status != Gdiplus::Ok)
{
hr = E_FAIL;
}
}
if (SUCCEEDED(hr))
{
for (UINT j = 0; j < nEncoders && !found; j++)
{
if (pImageCodecInfo[j].MimeType == format)
{
*pGuid = pImageCodecInfo[j].Clsid;
found = true;
}
}
hr = found ? S_OK : E_FAIL;
}
return hr;
}
int main()
{
Gdiplus::GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
GUID guidBmp = {};
GUID guidJpeg = {};
GUID guidGif = {};
GUID guidTiff = {};
GUID guidPng = {};
GetGdiplusEncoderClsid(L"image/bmp", &guidBmp);
GetGdiplusEncoderClsid(L"image/jpeg", &guidJpeg);
GetGdiplusEncoderClsid(L"image/gif", &guidGif);
GetGdiplusEncoderClsid(L"image/tiff", &guidTiff);
GetGdiplusEncoderClsid(L"image/png", &guidPng);
return 0;
}
#包括
#包括
#包括
#包括
HRESULT GetGdiplusEncoderClsid(常量std::wstring&格式,GUID*pGuid)
{
HRESULT hr=S_正常;
UINT nEncoders=0;//图像编码器的数量
UINT nSize=0;//图像编码器数组的大小(字节)
std::矢量spData;
Gdiplus::ImageCodecInfo*pImageCodecInfo=NULL;
Gdiplus::状态;
bool-found=false;
if(format.empty()| |!pGuid)
{
hr=E_INVALIDARG;
}
如果(成功(hr))
{
*pGuid=GUID\u NULL;
status=Gdiplus::GetImageEncodersSize(&nEncoders,&nSize);
if((状态!=Gdiplus::Ok)| |(nSize==0))
{
hr=E_失败;
}
}
如果(成功(hr))
{
spData.resize(nSize);
pImageCodecInfo=(Gdiplus::ImageCodecInfo*)&spData.front();
status=Gdiplus::GetImageEncoders(nEncoders、nSize、pImageCodecInfo);
如果(状态!=Gdiplus::Ok)
{
hr=E_失败;
}
}
如果(成功(hr))
{
对于(UINT j=0;j
如果您只想编写一个PNG,这似乎是可行的:
// image/png : {557cf406-1a04-11d3-9a73-0000f81ef32e}
const CLSID pngEncoderClsId = { 0x557cf406, 0x1a04, 0x11d3,{ 0x9a,0x73,0x00,0x00,0xf8,0x1e,0xf3,0x2e } };
stat = image->Save(L"test.png", &pngEncoderClsId, NULL);
注意十六进制值的重新格式化
发件人:
这正是我试图做的,但是
GetEncoderClsid
不是GDI+的一部分-您必须从文档中复制它。这些CLSID在注册表中不存在。我能找到的唯一一个真正存在于注册表中的编解码器CLSID是针对Windows Imaging Component(WIC)编解码器的,而不是GDI+编解码器。GDI+的Image::Save()是否使用硬编码列表将它接收到的编码器CLSID映射到实际的编码器?为什么GUI在注册表中很重要?如果它们在注册表的CLSID键中,这意味着它们可以像普通COM类一样从GDI+之外使用(毕竟CLSID就是这个意思)。但更重要的是,我希望有一个键引用所有编解码器,其中可以添加编解码器以实现可扩展性。不幸的是,GDI+似乎不能用新的编解码器进行扩展,只有WIC可以。GetEncoderCSID(L“image/png”,…)由于某种原因不能工作,但这个工作很好。