// Die GetEncoderClsid() Funktion wurde einfach aus der MSDN/PSDK Doku kopiert. // Zu finden mit dem Suchstring "Retrieving the Class Identifier for an Encoder" // Sucht zu z.B. 'image/jpeg' den passenden Encoder und liefert dessen CLSID... int GetEncoderClsid(const wchar_t *format, CLSID *pClsid) { UINT num = 0; // number of image encoders UINT size = 0; // size of the image encoder array in bytes UINT j; ImageCodecInfo* pImageCodecInfo = NULL; GdipGetImageEncodersSize(&num, &size); if(size == 0) return -1; // Failure pImageCodecInfo = (ImageCodecInfo*)(malloc(size)); if(pImageCodecInfo == NULL) return -1; // Failure GdipGetImageEncoders(num, size, pImageCodecInfo); for( j = 0; j < num; ++j ) { if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 ) { *pClsid = pImageCodecInfo[j].Clsid; free(pImageCodecInfo); return j; // Success } } free(pImageCodecInfo); return -1; // Failure }
static void pSaveImageAs(HWND hwnd) { OPENFILENAMEW sfn; ImageCodecInfo *codecInfo; WCHAR szSaveFileName[MAX_PATH]; WCHAR *szFilterMask; GUID rawFormat; UINT num; UINT size; UINT sizeRemain; UINT j; WCHAR *c; GdipGetImageEncodersSize(&num, &size); codecInfo = malloc(size); if (!codecInfo) { DPRINT1("malloc() failed in pSaveImageAs()\n"); return; } GdipGetImageEncoders(num, size, codecInfo); GdipGetImageRawFormat(image, &rawFormat); sizeRemain = 0; for (j = 0; j < num; ++j) { // Every pair needs space for the Description, twice the Extensions, 1 char for the space, 2 for the braces and 2 for the NULL terminators. sizeRemain = sizeRemain + (((wcslen(codecInfo[j].FormatDescription) + (wcslen(codecInfo[j].FilenameExtension) * 2) + 5) * sizeof(WCHAR))); } /* Add two more chars for the last terminator */ sizeRemain = sizeRemain + (sizeof(WCHAR) * 2); szFilterMask = malloc(sizeRemain); if (!szFilterMask) { DPRINT1("cannot allocate memory for filter mask in pSaveImageAs()"); free(codecInfo); return; } ZeroMemory(szSaveFileName, sizeof(szSaveFileName)); ZeroMemory(szFilterMask, sizeRemain); ZeroMemory(&sfn, sizeof(sfn)); sfn.lStructSize = sizeof(sfn); sfn.hwndOwner = hwnd; sfn.hInstance = hInstance; sfn.lpstrFile = szSaveFileName; sfn.lpstrFilter = szFilterMask; sfn.nMaxFile = MAX_PATH; sfn.Flags = OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY; c = szFilterMask; for (j = 0; j < num; ++j) { StringCbPrintfExW(c, sizeRemain, &c, &sizeRemain, 0, L"%ls (%ls)", codecInfo[j].FormatDescription, codecInfo[j].FilenameExtension); /* Skip the NULL character */ c++; sizeRemain -= sizeof(*c); StringCbPrintfExW(c, sizeRemain, &c, &sizeRemain, 0, L"%ls", codecInfo[j].FilenameExtension); /* Skip the NULL character */ c++; sizeRemain -= sizeof(*c); if (IsEqualGUID(&rawFormat, &codecInfo[j].FormatID) == TRUE) { sfn.nFilterIndex = j + 1; } } if (GetSaveFileNameW(&sfn)) { if (GdipSaveImageToFile(image, szSaveFileName, &codecInfo[sfn.nFilterIndex - 1].Clsid, NULL) != Ok) { DPRINT1("GdipSaveImageToFile() failed\n"); } } free(szFilterMask); free(codecInfo); }