C++ 连载:CArchive a CImage
我目前正试图找出如何在CArchive(JPEG)中正确存储CImage文件。我目前的方法是以下(伪)代码: 我刚刚回到C++,过去只做了一点。任何帮助都将不胜感激C++ 连载:CArchive a CImage,c++,image,serialization,mfc,carchive,C++,Image,Serialization,Mfc,Carchive,我目前正试图找出如何在CArchive(JPEG)中正确存储CImage文件。我目前的方法是以下(伪)代码: 我刚刚回到C++,过去只做了一点。任何帮助都将不胜感激 非常感谢您。我不是IStream的专家,但我认为您可能没有正确使用它。下面的代码似乎有效。它目前以png格式存档,但可以通过Gdiplus::ImageFormatPNG轻松更改。 这在很大程度上要归功于S.Arman在《将IStream视为字节流》的教程 void ImageArchive(CImage*pImage、CArch
非常感谢您。我不是IStream的专家,但我认为您可能没有正确使用它。下面的代码似乎有效。它目前以png格式存档,但可以通过Gdiplus::ImageFormatPNG轻松更改。 这在很大程度上要归功于S.Arman在《将IStream视为字节流》的教程
void ImageArchive(CImage*pImage、CArchive&ar)
{
HRESULT-hr;
if(ar.IsStoring())
{
//创建流
IStream*pStream=SHCreateMemStream(NULL,0);
断言(pStream!=NULL);
if(pStream==NULL)
返回;
//将映像写入流而不是文件(在本例中,流只是由流本身自动分配的内存块)
pImage->Save(pStream,Gdiplus::ImageFormatPNG);//注意:IStream将根据需要自动增长。
//查找写入的内存大小(即图像文件大小)
STATSTG statsg;
hr=pStream->Stat(&statsg,STATFLAG_NONAME);
断言(hr==S_OK);
断言(statsg.cbSize.QuadPartSeek(seekPos,STREAM\u Seek\u SET,NULL);
断言(hr==S_OK);
//将流中的数据获取到标准字节数组中
char*bytes=新字符[nImgBytes];
ULONG nRead;
hr=pStream->Read(bytes,nImgBytes,&nRead);//将数据从流中读取到正常内存中。nRead应等于statsg.cbSize.QuadPart。
断言(hr==S_OK);
断言(nImgBytes==nRead);
//将数据写入存档并完成
ar释放();
删除[]字节;
}
其他的
{
//从存档中获取数据
ULONG-nBytes;
ar>>nBytes;
char*bytes=new char[nBytes];//用于保存存档文件中数据的普通内存
UINT nBytesRead=ar.Read(bytes,nBytes);//从存档文件中读取数据
断言(nBytesRead==UINT(nBytes));
//顺流而下
IStream*pStream=SHCreateMemStream(NULL,0);
断言(pStream!=NULL);
if(pStream==NULL)
返回;
//将归档数据放入流中
ULONG nbyteswrited;
pStream->Write(字节、nBytes和NByteswrited);
断言(nBytes==nbyteswrited);
如果(n字节!=n字节写入)
返回;
//转到流的开头
大整数seekPos;
seekPos.QuadPart=0;
hr=pStream->Seek(seekPos,STREAM\u Seek\u SET,NULL);
断言(hr==S_OK);
//将流装入CImage并完成
pImage->Load(pStream);//将存档数据传递给CImage
pStream->Release();
删除[]字节;
}
}
在问答网站上提问通常是个好主意。你没有问一个问题。根本不清楚你想解决什么问题。你的代码有效吗?您的代码是否失败(如果失败,如何失败)?您是否只需要代码的反馈?您是否正在寻找开发人员为您编写代码?还有别的吗?
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);
}
}
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;
}
}