Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > CreateStreamOnHGlobal


Автор: Andrey44 22.6.2009, 10:01
Всем доброго утра.
Вопрос в следующем:
У меня есть набор байт - это картинка jpg которую я загружаю в массив из БД
Потом мне эту картинку надо отобразить в окне, но что-то никак не могу это сделать.
Вот код создания картинки из массива байт:
Код

CByteArray byteArr;
    olevar.GetByteArrayFromVariantArray(byteArr);

    //BYTE *data = byteArr.GetData();


    Gdiplus::Status st;
    INT_PTR imageSize = byteArr.GetSize();
    if (!imageSize)
        return;
    const void* pResourceData = byteArr.GetData();
    if (!pResourceData)
        return;
    HGLOBAL hBuffer  = ::GlobalAlloc(GMEM_MOVEABLE, imageSize);
    if (hBuffer)
    {
        void* pBuffer = ::GlobalLock(hBuffer);
        if (pBuffer)
        {
            CopyMemory(pBuffer, pResourceData, imageSize);
            IStream* pStream = NULL;
            if (::CreateStreamOnHGlobal(hBuffer, FALSE, &pStream) == S_OK)
            {
                _img = Gdiplus::Image::FromStream(pStream);
                st = _img->GetLastStatus();//тут всегда invalidParameter
            }
            ::GlobalUnlock(hBuffer);
        }
        ::GlobalFree(hBuffer);
        hBuffer = NULL;
    }

    Invalidate();

Подскажите, что не так делаю?
Убил уже 2 часа времени и никак smile 

Автор: Andrey44 22.6.2009, 12:26
Все перепроверил, и получилось что не правильно читал и записывал байты в БД.
Читал файл:
Код

std::ifstream inFile(path);

    if(inFile == 0)return;
    inFile.seekg (0, std::ios::end);
    __int64 sizefile = inFile.tellg();
    inFile.seekg (0, std::ios::beg);
    
    byteArr.SetSize(sizefile);
    BYTE *data = byteArr.GetData();

    inFile.read(
        (char*)data, // буффер
        (UINT)sizefile);    // количество читаемых в буфер байт

    inFile.close();
Но так читались не все байты, и почти весь byteArr записывался нулями.
Теперь читаю:
Код

    CStdioFile f(path, CFile::modeRead);
    __int64 sizefile = f.GetLength();

    byteArr.SetSize(sizefile);
    BYTE *data = byteArr.GetData();

    f.Read(data, sizefile);
    f.Close();
Читаются вроде как все байты, но при сохранении в картинку получается что байты или смещаются или что-то не так.
Вот две картинки:
1)до сохранения
http://ipicture.ru/
2)после
http://ipicture.ru/

Сохраняю картинку так:
Код

CStdioFile f(_T("D:\\testImage.bmp"), CFile::modeWrite | CFile::modeCreate);
    f.Write(byteArr.GetData(), imageSize);
    f.Close();

Что делать, как читать и писать? smile 

Автор: Andrey44 22.6.2009, 12:49
С записью и чтением разобрался.
Надо было добавить флаг
Код

CFile::typeBinary

Теперь картинка получается как она должна быть, но теперь не могу нарисовать картинку.
Как из массива байт получить картинку Gdiplus::Image?

Автор: Andrey44 23.6.2009, 09:16
 smile Ну неужели никто никогда не делал такого?
Если сохранить массив байтов в файл и открыть его , то получается нормальная картинка, 
НО мне надо без сохранения в файл. Как из массива байтов получить Gdiplus::Image ???

Автор: jonie 23.6.2009, 09:36
http://www.eggheadcafe.com/forumarchives/win32programmergdi/Jan2006/post25116322.asp
зачитай-ка.
ну и вообще гугл - трабла-то стандартная должно быть.

Автор: Andrey44 23.6.2009, 09:57
jonie, спасибо за помощь, уже разобрался.
Я освобождал память ::GlobalFree(hBuffer);, а картинка думала что с памятью у нее все нормально smile , а ее уже не было.
Теперь переписал ::CreateStreamOnHGlobal(hBuffer, FALSE, &pStream) на 
::CreateStreamOnHGlobal(hBuffer, TRUE, &pStream), теперь память освобождается когда картинка умирает.
А я столько времени потратил!

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)