Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: GetEncoderClsid: сохраненный JPG-файл 0-го размера, GetEncoderClsid(L"image/jpg"  (Прочитано 10211 раз)
0 Пользователей и 1 Гость смотрят эту тему.
malor
Опытный

ru
Offline Offline

« : 26-06-2011 09:49 » 

Вроде работал, но что-то перестал. Почему-то сохраняет файл имеющий 0-й размер.
Код: (C++)
// http://msdn.microsoft.com/en-us/library/ms533843.aspx
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
}

// Сохраннение в файл на диске в формате JPG
void SaveScreenShotJPG()
{
    ULONG_PTR gdiplusToken;
    GdiplusStartupInput gdiplusStartupInput;
    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(Width, Height);
    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/jpg", &imgClsid);
    int status;
    status = img->Save(L"Z:\\ImageDesktop.jpg", &imgClsid, &encoderParams);
    delete bmp;
    delete img;
}
Что не так?

Вот такой работает (здесь BMP-формат):
Код: (C++)
// Сохраннение в файл на диске в формате BMP
void SaveScreenShotBMP()
{
    ULONG_PTR gdiplusToken;
    GdiplusStartupInput gdiplusStartupInput;
    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(Width, Height);
    CLSID imgClsid;
    GetEncoderClsid(L"image/bmp", &imgClsid);
    int status;
    status = img->Save(L"Z:\\ImageDesktop.bmp", &imgClsid);
    delete bmp;
    delete img;
}
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #1 : 27-06-2011 11:01 » 

Вроде работал, но что-то перестал.

Не верю! (с) Ага С MIME типом jpg.  Надо jpeg.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
malor
Опытный

ru
Offline Offline

« Ответ #2 : 29-06-2011 14:54 » 

Сохраняю скриншот экрана с периодом полсекунды в JPG-файл. После 85-86 раз скрин уже не создавался - функция
img->Save(L"Z:\\ImageDesktop.jpeg", &imgClsid, &encoderParams);
возвращала значение 2.
Почему ?
Скрины делал по таймеру с интервалами 0.5 сек, 1 сек, 2 сек.

Код: (C++)
// http://msdn.microsoft.com/en-us/library/ms533843.aspx
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
}

// Сохраннение в файл на диске в формате JPG
void SaveScreenShotJPG()
{
    static int GoodWork = 0;

    ULONG_PTR gdiplusToken;
    GdiplusStartupInput gdiplusStartupInput;
    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(Width, Height);
    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"Z:\\ImageDesktop.jpeg", &imgClsid, &encoderParams);
    if (!status)
        GoodWork = GoodWork + 1;
    delete bmp;
    delete img;
}



P.S. С форматом BMP аналогичная ситуация.
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #3 : 29-06-2011 17:16 » 

Попробуй поискать утечки - похоже на то. В первой функции их точно нет.
И вместо возврата специальных значений лучше выбрасывать исключения с поясняющим текстом - сразу станет проще искать причину неисправности.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #4 : 29-06-2011 19:55 » 

А ещё лучше, посмотреть, что же всё-таки означает status=2, и пройтись дебаггером.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
malor
Опытный

ru
Offline Offline

« Ответ #5 : 03-07-2011 12:53 » 

На строке
status = img->Save(L"Z:\\ImageDesktop.jpeg", &imgClsid, &encoderParams);
жмем F11 попадаем внутрь функции:
Код:
inline Status
Image::Save(
    IN const WCHAR* filename,
    IN const CLSID* clsidEncoder,
    IN const EncoderParameters *encoderParams
    )
{
    return SetStatus(DllExports::GdipSaveImageToFile(nativeImage,
                                                     filename,
                                                     clsidEncoder,
                                                     encoderParams));
}
Жмем F11 на строке
SetStatus(DllExports::GdipSaveImageToFile(nativeImage, filename, clsidEncoder, encoderParams)
оказываемся здесь:
Код:
Status SetStatus(Status status) const
{
   if (status != Ok)
      return (lastResult = status);
   else
      return status;
}

Как попасть внутрь "DllExports::GdipSaveImageToFile(...)" ?
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines