gdi+ потоки

Тема в разделе "LANGS.C", создана пользователем bug1z, 16 дек 2011.

  1. bug1z

    bug1z New Member

    Публикаций:
    0
    Регистрация:
    27 дек 2008
    Сообщения:
    228
    Добрый день.
    Есть некий код, который сохраняет изображение в поток IStream и производит различные манипуляции над ним.
    Поток создается как:

    Код (Text):
    1. IStream *stream = 0;
    2. CreateStreamOnHGlobal(NULL, TRUE, &stream);
    3. ...
    4. screenshot->Save(stream, &jpeg);
    5. // манипуляции
    6. stream->Releae();
    Этот код обернут в функцию и вызывается в цикле.
    Проблема вот в чем: ф-я отрабатывает нормально несколько итераций цикла(может быть 10, может за 100) и ни с того ни с чего Save возвращает 2(что говорит о том, что некий из параметров не валидный).

    Поскольку параметров всего два, а jpeg - это обычный CLSID то остается только стрим.
    Но я вызываю Release.

    В чем может быть проблема?

    Спасибо.
     
  2. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    bug1z
    screenshot — это ведь Gdiplus::Bitmap ? Save каким-то образом перегружен или как Вам удалось скомпилировать такой код без ошибок? Метод-то три параметра принимает, а не два.
     
  3. bug1z

    bug1z New Member

    Публикаций:
    0
    Регистрация:
    27 дек 2008
    Сообщения:
    228
    Да, screenshot - это
    Код (Text):
    1. Gdiplus::Bitmap *screenshot;
    Компилятор это скушал.
    Самое странное - это то, что оно работает-работает нормально, а затем какой то параметр почему то становится не валидным.

    сей час добавлю третий параметр и проверю.
     
  4. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    bug1z
    Ну дык что значит "какой-то"? Третий, естессно, раз он при вызове отсутствует, а вместо него мусор из стека подставляется. Только я до сих пор не пойму, как у Вас вызов Save с двумя параметрами компилируется.
     
  5. bug1z

    bug1z New Member

    Публикаций:
    0
    Регистрация:
    27 дек 2008
    Сообщения:
    228
    Ааа, вот же в мсдн написано:

    вписал ноль - проблема не решилась.
     
  6. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    bug1z
    Ну... Предлагаю проверить на моём старом коде, будет ли возникать та же проблема:
    Код (Text):
    1. DWORD SaveScreenSnapshot(DWORD Quality, char *&SSnapshotPtr, DWORD &SSnapshotSize)
    2. {
    3.     HDC DisplayDC, dcDesktBMP;
    4.     HBITMAP hDesktBMP;
    5.     Gdiplus::GdiplusStartupInput gdipSI;
    6.     Gdiplus::EncoderParameters encoderParams;
    7.     DWORD gdipToken; LARGE_INTEGER SeekPos = {0};
    8.     CLSID clsidEncoder = JPEGEncoderGUID;
    9.     STATSTG JPGInfo;
    10.     IStream *ScreenSnapshotStream;
    11.     VirtualFree(SSnapshotPtr,0,MEM_RELEASE);
    12.     DisplayDC = GetWindowDC(0);
    13.     hDesktBMP = CreateCompatibleBitmap(DisplayDC,GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN));
    14.     dcDesktBMP = CreateCompatibleDC(DisplayDC);
    15.     SelectObject(dcDesktBMP,hDesktBMP);
    16.     BitBlt(dcDesktBMP,0,0,GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN),DisplayDC,0,0,SRCCOPY);
    17.     gdipSI.GdiplusVersion = 1;
    18.     Gdiplus::GdiplusStartup(&gdipToken,&gdipSI,NULL);
    19.         Gdiplus::Bitmap *frDesktopBitmap = new Gdiplus::Bitmap(hDesktBMP,NULL);
    20.         CreateStreamOnHGlobal(NULL,true,&ScreenSnapshotStream);
    21.         encoderParams.Count = 1;
    22.         encoderParams.Parameter[0].Guid = Gdiplus::EncoderQuality;
    23.         encoderParams.Parameter[0].Type = Gdiplus::EncoderParameterValueTypeLong;
    24.         encoderParams.Parameter[0].NumberOfValues = 1;
    25.         encoderParams.Parameter[0].Value = &Quality;
    26.         frDesktopBitmap->Save(ScreenSnapshotStream,&clsidEncoder,&encoderParams);
    27.         ScreenSnapshotStream->Stat(&JPGInfo,STATFLAG_DEFAULT);
    28.         SSnapshotPtr = (char *)VirtualAlloc(NULL,JPGInfo.cbSize.LowPart,MEM_COMMIT,PAGE_READWRITE);
    29.         ScreenSnapshotStream->Seek(SeekPos,STREAM_SEEK_SET,NULL);
    30.         ScreenSnapshotStream->Read(SSnapshotPtr,JPGInfo.cbSize.LowPart,NULL);
    31.         SSnapshotSize = JPGInfo.cbSize.LowPart;
    32.         ScreenSnapshotStream->Release();
    33.         delete(frDesktopBitmap);
    34.     Gdiplus::GdiplusShutdown(gdipToken);
    35.     DeleteDC(dcDesktBMP);
    36.     DeleteObject(hDesktBMP);
    37.     ReleaseDC(0,DisplayDC);
    38.     return 0;
    39. }
    P.S. Ах да.
    const GUID JPEGEncoderGUID = {0x557CF401,0x1A04,0x11D3, {0x9A,0x73,0x00,0x00,0xF8,0x1E,0xF3,0x2E}};
     
  7. bug1z

    bug1z New Member

    Публикаций:
    0
    Регистрация:
    27 дек 2008
    Сообщения:
    228
    В вашем коде Save тоже возвращает 2.

    Правда, я его немного переделал под свой проект:
    Код (Text):
    1. DWORD Screenshot::SaveScreenSnapshot(std::vector<char> &vec, DWORD Quality/*, char *&SSnapshotPtr*/, DWORD &SSnapshotSize)
    2. {
    3.     HDC DisplayDC, dcDesktBMP;
    4.     HBITMAP hDesktBMP;
    5.     Gdiplus::GdiplusStartupInput gdipSI;
    6.     Gdiplus::EncoderParameters encoderParams;
    7.     DWORD gdipToken; LARGE_INTEGER SeekPos = {0};
    8.     const GUID JPEGEncoderGUID = {0x557CF401,0x1A04,0x11D3, {0x9A,0x73,0x00,0x00,0xF8,0x1E,0xF3,0x2E}};
    9.     CLSID clsidEncoder = JPEGEncoderGUID;
    10.     STATSTG JPGInfo;
    11.     IStream *ScreenSnapshotStream;
    12. //  VirtualFree(SSnapshotPtr,0,MEM_RELEASE);
    13.     DisplayDC = GetWindowDC(0);
    14.     hDesktBMP = CreateCompatibleBitmap(DisplayDC,GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN));
    15.     dcDesktBMP = CreateCompatibleDC(DisplayDC);
    16.     SelectObject(dcDesktBMP,hDesktBMP);
    17.     BitBlt(dcDesktBMP,0,0,GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN),DisplayDC,0,0,SRCCOPY);
    18.     gdipSI.GdiplusVersion = 1;
    19.     Gdiplus::GdiplusStartup(&gdipToken,&gdipSI,NULL);
    20.     Gdiplus::Bitmap *frDesktopBitmap = new Gdiplus::Bitmap(hDesktBMP,NULL);
    21.     CreateStreamOnHGlobal(NULL,true,&ScreenSnapshotStream);
    22.  
    23.  
    24.  
    25.  
    26.     encoderParams.Count = 1;
    27.     encoderParams.Parameter[0].Guid = Gdiplus::EncoderQuality;
    28.     encoderParams.Parameter[0].Type = Gdiplus::EncoderParameterValueTypeLong;
    29.     encoderParams.Parameter[0].NumberOfValues = 1;
    30.     encoderParams.Parameter[0].Value = &Quality;
    31.     std::cout << "::::" << frDesktopBitmap->Save(ScreenSnapshotStream,&clsidEncoder,&encoderParams);
    32.  
    33.  
    34.  
    35.     ScreenSnapshotStream->Stat(&JPGInfo,STATFLAG_DEFAULT);
    36. //  SSnapshotPtr = (char *)VirtualAlloc(NULL,JPGInfo.cbSize.LowPart,MEM_COMMIT,PAGE_READWRITE);
    37.     ScreenSnapshotStream->Seek(SeekPos,STREAM_SEEK_SET,NULL);
    38.     vec.resize(JPGInfo.cbSize.LowPart);
    39.     ScreenSnapshotStream->Read(&vec[0],JPGInfo.cbSize.LowPart,NULL);
    40.     SSnapshotSize = JPGInfo.cbSize.LowPart;
    41.     ScreenSnapshotStream->Release();
    42.     delete(frDesktopBitmap);
    43.     Gdiplus::GdiplusShutdown(gdipToken);
    44.     DeleteDC(dcDesktBMP);
    45.     DeleteObject(hDesktBMP);
    46.     ReleaseDC(0,DisplayDC);
    47.     return 0;
    48. }
    Но вроде ничего существенного не изменил.
     
  8. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    bug1z
    Вроде ничего не трётся. У меня этот код всегда работал. Поэтому не знаю. :)
     
  9. bug1z

    bug1z New Member

    Публикаций:
    0
    Регистрация:
    27 дек 2008
    Сообщения:
    228
    а может быть из за версии gdi+?
    может там какой баг(уж простите за такое предположение)?
     
  10. bug1z

    bug1z New Member

    Публикаций:
    0
    Регистрация:
    27 дек 2008
    Сообщения:
    228
    Убрал потоки. Осталась та же проблема. В чем может быть дело?