2017-01-06 2 views
0

В настоящее время я пытаюсь выяснить, как правильно хранить файл CImage в CArchive (JPEG). Мой текущий подход к этому является следующее (псевдо-код):Сериализация: CArchive a CImage

BOOL CPicture::Serialize(CArchive &ar) 
{ 
    IStream *pStream = NULL; 
    HRESULT hr; 
    CImage *img = GetImage(); 

    if (ar.IsLoading()) 
    { 
    HGLOBAL hMem = GlobalAlloc(GMEM_FIXED, 54262); 
    hr = CreateStreamOnHGlobal(hMem, FALSE, &pStream); 
    if(SUCCEEDED(hr)) 
    { 
     ar.Read(pStream, 54262); 
     img->Load(pStream); 
     pStream->Release(); 
     GlobalUnlock(hMem); 
     GlobalFree(hMem); 
    } 
    } 
    else 
    { 
    hr = CreateStreamOnHGlobal(0, TRUE, &pStream); 
    if (SUCCEEDED(hr)) 
    { 
     hr = img->Save(pStream, Gdiplus::ImageFormatJPEG); 
     if (SUCCEEDED(hr)) 
     ar.Write(pStream, 54262); 
    } 
    } 

...

Я только сейчас обратно в C++ и только сделал немного с ним в прошлом. Любая помощь будет очень высоко ценится.

спасибо, что заранее.

+4

Как правило, это хорошая идея задать вопрос на сайте Q & A. Вы не задали вопрос. Не совсем ясно, какую проблему вы пытаетесь решить. Работает ли ваш код? Прерывает ли ваш код (если да, как)? Вам просто нужна обратная связь по вашему коду? Вы ищете разработчика для написания кода для вас? Что-то другое? – IInspectable

ответ

0

Я не специалист по IStream, но думаю, что вы не можете использовать его правильно. Кажется, что работает следующий код. В настоящее время он архивирует в формате png, но его можно легко изменить с помощью Gdiplus :: ImageFormatPNG. Он во многом обязан учебнику «Охватывая IStream как просто поток байтов» С. Армана по адресу CodeProject.

void ImageArchive(CImage *pImage, CArchive &ar) 
{ 
    HRESULT hr; 
    if (ar.IsStoring()) 
    { 
// create a stream 
     IStream *pStream = SHCreateMemStream(NULL, 0); 
     ASSERT(pStream != NULL); 
     if (pStream == NULL) 
      return; 

// write the image to a stream rather than file (the stream in this case is just a chunk of memory automatically allocated by the stream itself) 
     pImage->Save(pStream, Gdiplus::ImageFormatPNG); // Note: IStream will automatically grow up as necessary. 

// find the size of memory written (i.e. the image file size) 
     STATSTG statsg; 
     hr = pStream->Stat(&statsg, STATFLAG_NONAME); 
     ASSERT(hr == S_OK); 
     ASSERT(statsg.cbSize.QuadPart < ULONG_MAX); 
     ULONG nImgBytes = ULONG(statsg.cbSize.QuadPart); // any image that can be displayed had better not have more than MAX_ULONG bytes 

// go to the start of the stream 
     LARGE_INTEGER seekPos; 
     seekPos.QuadPart = 0; 
     hr = pStream->Seek(seekPos, STREAM_SEEK_SET, NULL); 
     ASSERT(hr == S_OK); 

// get data in stream into a standard byte array 
     char *bytes = new char[nImgBytes]; 
     ULONG nRead; 
     hr = pStream->Read(bytes, nImgBytes, &nRead); // read the data from the stream into normal memory. nRead should be equal to statsg.cbSize.QuadPart. 
     ASSERT(hr == S_OK); 
     ASSERT(nImgBytes == nRead); 

// write data to archive and finish 
     ar << nRead; // need to save the amount of memory needed for the file, since we will need to read this amount later 
     ar.Write(bytes, nRead);  // write the data to the archive file from the stream memory 
     pStream->Release(); 
     delete[] bytes; 
    } 
    else 
    { 
// get the data from the archive 
     ULONG nBytes; 
     ar >> nBytes; 
     char *bytes = new char[nBytes]; // ordinary memory to hold data from archive file 
     UINT nBytesRead = ar.Read(bytes, nBytes); // read the data from the archive file 
     ASSERT(nBytesRead == UINT(nBytes)); 

// make the stream 
     IStream *pStream = SHCreateMemStream(NULL, 0); 
     ASSERT(pStream != NULL); 
     if (pStream == NULL) 
      return; 

// put the archive data into the stream 
     ULONG nBytesWritten; 
     pStream->Write(bytes, nBytes, &nBytesWritten); 
     ASSERT(nBytes == nBytesWritten); 
     if (nBytes != nBytesWritten) 
      return; 

// go to the start of the stream 
     LARGE_INTEGER seekPos; 
     seekPos.QuadPart = 0; 
     hr = pStream->Seek(seekPos, STREAM_SEEK_SET, NULL); 
     ASSERT(hr == S_OK); 

// load the stream into CImage and finish 
     pImage->Load(pStream); // pass the archive data to CImage 
     pStream->Release(); 
     delete[] bytes; 
    } 
} 
Смежные вопросы