Ли в GDI+ есть стандарт идентификаторов датчика изображения?
GDI+ Image::Save
метод требует параметра CLSID для указания используемого кодера. Документация указывает на некоторый пример кода для получения кодера, связанного с определенным типом MIME, таким как image/jpeg или image/png. Однако я отказываюсь от мысли о копировании функции на полстраницы только для поддержки 1-строчного средства отладки, где я сохраняю промежуточный результат на диск.
Разве не должен быть список стандартных CLSID для стандартных кодеров? Где найду ли я такой список? Я не смог найти его, поискав включенные файлы Microsoft.
3 ответа:
Такого нет. Я думаю, что они хотели, чтобы список кодеков был расширяемым и поддерживал плагины, но так и не смогли до него добраться. Учитывая, что они не внесли никаких изменений в GDI+ в течение довольно долгого времени, они, вероятно, не будут в ближайшее время. Возможно, Вам сойдет с рук создание собственного жестко закодированного списка на основе перечисления Gdiplus:: GetImageEncoders.
То есть:
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 кодировщика. Вы можно изменить его, чтобы он был поиском по таблице.
HRESULT GetGdiplusEncoderClsid(__in LPCWSTR pwszFormat, __out GUID *pGUID) { HRESULT hr = E_FAIL; UINT nEncoders = 0; // number of image encoders UINT nSize = 0; // size of the image encoder array in bytes CAutoVectorPtr<BYTE> spData; Gdiplus::ImageCodecInfo* pImageCodecInfo = NULL; Gdiplus::Status status; bool fFound = false; // param check if ((pwszFormat == NULL) || (pwszFormat[0] == 0) || (pGUID == NULL)) { return E_POINTER; } *pGUID = GUID_NULL; status = Gdiplus::GetImageEncodersSize(&nEncoders, &nSize); if ((status != Gdiplus::Ok) || (nSize == 0)) { return E_FAIL; } spData.Allocate(nSize); if (spData == NULL) { return E_FAIL; } pImageCodecInfo = (Gdiplus::ImageCodecInfo*)(BYTE*)spData; status = Gdiplus::GetImageEncoders(nEncoders, nSize, pImageCodecInfo); if (status != Gdiplus::Ok) { return E_FAIL; } for(UINT j = 0; j < nEncoders; ++j) { if( wcscmp(pImageCodecInfo[j].MimeType, pwszFormat) == 0 ) { *pGUID = pImageCodecInfo[j].Clsid; fFound = true; break; } } hr = fFound ? S_OK : E_FAIL; return hr; }
Вы, вероятно, захотите использовать
ImageCodecInfo
сGetImageEncodersSize()
иGetImageEncoders()
я не знаю более простого способа.EDIT: если вы точно знаете, чего хотите, и черт бы побрал все остальное, вам может сойти с рук что-то подобное ...
CLSID pngClsid; GetEncoderClsid("image/png", &pngClsid); image.Save("imagename.png", &pngClsid, NULL);
Если вы просто хотите написать 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);
Обратите внимание на переформатирование шестнадцатеричных значений.