Проблема в функции CreateCompatibleBitmap: на 29 кадре возвращает нуль и код ошибки 8 (ERROR_NOT_ENOUGH_MEMORY). Причина: неправильно освобождается этот ресурс.
Код | #include <windows.h> #include <gdiplus.h> #include <tchar.h> #pragma comment (lib, "gdiplus.lib") using namespace Gdiplus;
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 ImageCodecInfo* pImageCodecInfo = NULL; GetImageEncodersSize(&num, &size); if(size == 0) return -1; // Failure pImageCodecInfo = (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 }
void GetScreen(LPWSTR filename) { int Width, Height; HDC scrdc, memdc; HBITMAP membit; scrdc = GetDC(0); Height = GetSystemMetrics(SM_CYSCREEN); Width = GetSystemMetrics(SM_CXSCREEN); memdc = CreateCompatibleDC(scrdc); membit = CreateCompatibleBitmap(scrdc, Width, Height); HGDIOBJ oldbit = SelectObject(memdc, membit); BitBlt(memdc, 0, 0, Width, Height, scrdc, 0, 0, SRCCOPY); Bitmap * bmp = new Bitmap(membit, NULL); Image * img = bmp->GetThumbnailImage(720, 540); CLSID imgClsid; EncoderParameters encoderParams; int quality = 65; encoderParams.Count = 1; encoderParams.Parameter[0].Guid = EncoderQuality; encoderParams.Parameter[0].Type = 4; encoderParams.Parameter[0].NumberOfValues = 1; encoderParams.Parameter[0].Value = &quality; GetEncoderClsid(L"image/jpeg", &imgClsid); int status; status = img->Save(filename, &imgClsid, &encoderParams); delete bmp; delete img; SelectObject(memdc, oldbit); // отсоединяет совм. битмап от совм. контекста. DeleteObject(membit); //ReleaseDC(0, memdc); // gdi resource leak (исправил: 26.01.2009) DelectObject(memdc); ReleaseDC(0, scrdc); }
int APIENTRY _tWinMain(HINSTANCE, HINSTANCE, LPCTSTR, INT) { ULONG_PTR gdiplusToken; GdiplusStartupInput gdiplusStartupInput; wchar_t buff[260];
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
for(int i = 0; i<100; ++i) { //if(i >= 28) __asm int 3; swprintf(buff, L"C:\\output\\%d.jpg", i); GetScreen(buff); } GdiplusShutdown(gdiplusToken); return 0; } |
|