Понадобилось мне тут сохранить созданный в памяти Bitmap в gif, поступил следующим образом: Нашёл в гугле процедуру получения CLSID кодека: Код (C): int GetEncoderClsid(const WCHAR* format, CLSID* pClsid) { UINT num = 0; // number of image encoders UINT size = 0; // size of the image encoder array in bytes Gdiplus::ImageCodecInfo* pImageCodecInfo = NULL; GetImageEncodersSize(&num, &size); if (size == 0) return -1; // Failure pImageCodecInfo = (Gdiplus::ImageCodecInfo*)(malloc(size)); if (pImageCodecInfo == NULL) return -1; // Failure 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; // Success } } free(pImageCodecInfo); return -1; // Failure } Вызвал её так: Код (C): CLSID CODCLSID; int index = GetEncoderClsid(L"image/gif", &CODCLSID); if (index == -1) { printf("Can not get encoder CLSID!\n"); getchar(); return 0; } Всё отработало нормально. Далее выделил память и пока-что забил её нулями: Код (C): #define PIC_SIZE 500 ... RGBQUAD *BitmapData = (RGBQUAD*)malloc(PIC_SIZE*PIC_SIZE*sizeof(RGBQUAD)); ZeroMemory(BitmapData, PIC_SIZE*PIC_SIZE*sizeof(RGBQUAD)); Ну, и в конце создал bitmap на основе BitmapData и попытался сохранить: Код (C): Bitmap bm(PIC_SIZE, PIC_SIZE, INT(0), PixelFormat32bppPARGB, (BYTE*)BitmapData); Stat = bm.Save(L"C:\\temp\\test.gif", &CODCLSID); В итоге Stat принемает значение InvalidParameter и файл не сохраняется. Вопрос как говорится в следующем: "в каком коде ошибка?", только не говорите, что в генетическом.
Привет. Сразу скажу, в Си плоховат, но есть несколько вопросов, - вызов bm.Save - есть возможность показать код функции Save? в приведенных исходниках его не видно. - есть возможность вызвать Save не для bm, а для другого куска памяти, ради теста, пусть для строки "1234567890" ? Сущность Save слишком размыта, чтобы сходу понять, почему возникает ошибка. InvalidParameter может относиться как к неверно переданным параметрам при вызове Save, так и быть следствием какой-то внутренней нестыковки (напр. оно может делать запись только в существующий файл; при попытке обратиться к несуществующему файлу она не создает его, и возвращает ошибку)
Это же просто метод COM-интерфейса Image::Save(). Вообще, с выходом семерки, первый вопрос, который возникает при виде путей вида "C:\\..." - а есть ли права на запись?
И продолжаю, натолкнув самого себя на мысль Раз это COM, то использовать надо BSTR. Это не совсем то же самое, что и обычная юникод-строка, там счетчик длины еще есть по отрицательному смещению.
Действительно, тупанул с параметром stride теперь всё работает. Это просто обёртка над вполне обычной функцией из gdiplus.dll и как я понимаю никакой не COM: Код (C++): inline Status Image::Save( IN const WCHAR* filename, IN const CLSID* clsidEncoder, IN const EncoderParameters *encoderParams ) { return SetStatus(DllExports::GdipSaveImageToFile(nativeImage, filename, clsidEncoder, encoderParams)); }