19,468
社区成员
发帖
与我相关
我的任务
分享
Bitmap* CreateBitmapFromMemory(const void *buf, size_t size)
{
IStream *stream = NULL;
HGLOBAL global = GlobalAlloc( GMEM_MOVEABLE, size );
if( NULL == global )
return NULL;
/* copy the buf content to the HGLOBAL */
if( !mem_to_global( buf, size, global ) )
{
GlobalFree( global );
return NULL;
}
/* get the IStream from the global object */
if( CreateStreamOnHGlobal( global, TRUE, &stream ) != S_OK )
{
GlobalFree( global );
return NULL;
}
/* create the image from the stream */
Bitmap *image = Bitmap::FromStream( stream, FALSE );
stream->Release();
/* I suppose when the reference count for stream is 0, it will
GlobalFree automatically. The Image maintain the object also.*/
return image;
}
void* SaveBitmapToMemory(Bitmap *image, void **outbuf, size_t *size, size_t CodecIndex, ULONG quality)
//outbuf在函数内malloc内存,因此需free掉
{
IStream *stream = NULL;
EncoderParameters encoderParameters,*pencoderParameters=NULL;
const static TCHAR CodecNames[][11]={
TEXT("image/jpeg"),
TEXT("image/bmp"),
TEXT("image/gif"),
TEXT("image/png"),
TEXT("image/tiff")};
if(CodecIndex>sizeof(CodecNames)/sizeof(CodecNames[0])-1)
return NULL;
if(0==CodecIndex)
pencoderParameters=&encoderParameters;
if( CreateStreamOnHGlobal( NULL, TRUE, &stream ) != S_OK )
return NULL;
CLSID jpgClsid;
if(-1==GetEncoderClsid(CodecNames[CodecIndex], &jpgClsid ))
return NULL;
/* save the image to stream */
if(quality>100)
quality=100;
encoderParameters.Count = 1;
encoderParameters.Parameter[0].Guid = EncoderQuality;
encoderParameters.Parameter[0].Type = EncoderParameterValueTypeLong;
encoderParameters.Parameter[0].NumberOfValues = 1;
encoderParameters.Parameter[0].Value = &quality;
Status save_s = image->Save( stream, &jpgClsid, pencoderParameters );
if( save_s != Ok )
{
stream->Release();
return NULL;
}
/* read the stream to buffer */
if( !stream_to_mem( stream, outbuf, size ) )
{
stream->Release();
return NULL;
}
stream->Release();//我加的
return *outbuf;
}
bool mem_to_global(const void *buf, size_t size, HGLOBAL global)
{
void *dest = GlobalLock( global );
if( NULL == dest )
{
return false;
}
memcpy( dest, buf, size );
GlobalUnlock( global );
return true;
}
bool stream_to_mem(IStream *stream, void **outbuf, size_t *size)
{
ULARGE_INTEGER ulnSize;
LARGE_INTEGER lnOffset;
lnOffset.QuadPart = 0;
/* get the stream size */
if( stream->Seek( lnOffset, STREAM_SEEK_END, &ulnSize ) != S_OK )
{
return false;
}
if( stream->Seek( lnOffset, STREAM_SEEK_SET, NULL ) != S_OK )
{
return false;
}
/* read it */
*outbuf = malloc( (size_t)ulnSize.QuadPart );
*size = (size_t) ulnSize.QuadPart;
ULONG bytesRead;
if( stream->Read( *outbuf, (ULONG)ulnSize.QuadPart, &bytesRead ) != S_OK )
{
free( *outbuf );
return false;
}
return true;
}