2017-01-06 100 views
0

我目前正試圖找出如何正確地存儲在一個CArchive(JPEG)的CImage文件。我目前的做法,這是下面的(僞)代碼:序列化:CArchive一個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

在問答網站上提問通常是個好主意。你沒有提出問題。你一直都不清楚你想要解決什麼問題。你的代碼是否工作?你的代碼是否失敗(如果是這樣,如何)?你只需要對你的代碼進行反饋?您是否在尋找一名開發人員爲您編寫代碼?還有別的嗎? – IInspectable

回答

0

我不是IStream的專家,但我認爲你可能沒有正確使用它。下面的代碼似乎工作。它目前以png格式存檔,但可以通過Gdiplus :: ImageFormatPNG輕鬆更改。 它很大程度上歸功於S.Arman在CodeProject上的教程「僅僅將字節流接受爲IStream」。

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; 
    } 
} 
相關問題