Модераторы: Rickert, Alexeis, BorisVorontsov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Проблема с GDI+, Сохранение в файл 
:(
    Опции темы
ppoger
Дата 22.3.2008, 18:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 31
Регистрация: 14.7.2007

Репутация: нет
Всего: нет



собственно имеется следующий код, который захватывает с экрана HBitmap, создает из него Image и сохраняет картинку в файл:

Эту функцию взял из Platform SDK
Код

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()
{
  GdiplusStartupInput gdiplusStartupInput; 
  ULONG_PTR gdiplusToken; 
  GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);


  
 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);
 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(L"c:\\123.jpg", &imgClsid, &encoderParams);


 delete bmp;
 delete img;



 GdiplusShutdown(gdiplusToken);
 
 DeleteObject(membit);
 ReleaseDC(0, memdc);
 ReleaseDC(0, scrdc);




и потом вызываю эту функцию, например так: 
Код

For (int i=0; i<200; i++) GetScreen();


Ну хочу я 200 скринов сделать например.
А теперь сама проблема. Первые 36 скринов нормально сохраняются, потом метод Save класса Image врзвращает ошибку IvalidParameter. пробовал сохранять в разные файлы - 0 эффекта. убирал третий параметр (который отвечает за сжатие) - 0 эффекта... Значит что то не то с этой микрософтской функцией?
Кто знает - отпишитесь smile
PM MAIL   Вверх
586
Дата 26.3.2008, 19:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2243
Регистрация: 8.5.2006

Репутация: нет
Всего: 146



Проблема в функции 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;
}


Это сообщение отредактировал(а) 586 - 26.1.2009, 04:28
PM   Вверх
ppoger
Дата 27.3.2008, 21:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 31
Регистрация: 14.7.2007

Репутация: нет
Всего: нет



спасибо) на этот момент не обращал внимания, думал проблема в гди+. еще раз спасибо)
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Вы можете найти полезным что...
Alexeis
Rickert
  • Английская документация по DirectX лежит где-то здесь.
  • Английская документация по OpenGL лежит где-то там.
  • Гейм-дев у нас обсуждают где-то тут

Ждём вас! С уважением, Alexeis, Rickert.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Мультимедия, OpenGL/DirectX | Следующая тема »


 




[ Время генерации скрипта: 0.1103 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.