图像格式转换我们有如下思路
1、使用开源库CXimage等
2、解析图像格式,自己开发图像库
3、使用GDI+
4、其他
今天我们使用GDI+作为图像处理的方法。GDI+可以做图层、图像的处理,但是他也有自身的不足,比如说效率、不能保持为内存对象。今天我们就解析如何将GDI+转换为内存对象以及如何将内存对象转化为GDI+对象,具体的看代码
static int GetEncoderClsid( const WCHAR *format, CLSID *pClsid )
{
UINT num = 0, size = 0;
Gdiplus::ImageCodecInfo *pImageCodecInfo = NULL;
Gdiplus::GetImageEncodersSize( &num, &size );
if( size == 0 )
{
return -1;
}
pImageCodecInfo = (Gdiplus::ImageCodecInfo*) malloc( size );
Gdiplus::GetImageEncoders( num, size, pImageCodecInfo );
for( UINT i = 0; i < num; ++ i )
{
if( wcscmp( pImageCodecInfo[i].MimeType, format ) == 0 )
{
*pClsid = pImageCodecInfo[i].Clsid;
free( pImageCodecInfo );
return i;
}
}
free( pImageCodecInfo );
return -1;
}
static bool mem_to_global( const void *buf, size_t size, HGLOBAL global )
{
void *dest = ::GlobalLock( global );
if( dest == NULL )
{
return false;
}
memcpy( dest, buf, size );
::GlobalUnlock( global );
return true;
}
static 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;
}
Gdiplus::Image *mi_from_memory( const void *buf, size_t size )
{
IStream *stream = NULL;
HGLOBAL global = ::GlobalAlloc( GMEM_MOVEABLE, size );
if( global == NULL )
{
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 */
Gdiplus::Image *image = Gdiplus::Image::FromStream( stream );
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 *mi_to_memory( Gdiplus::Image *image, void **outbuf, size_t *size )
{
IStream *stream = NULL;
if( ::CreateStreamOnHGlobal( NULL, TRUE, &stream ) != S_OK )
{
return NULL;
}
/* get the jpg encoder */
::CLSID jpgClsid;
GetEncoderClsid( L"image/jpeg", &jpgClsid );
/* save the image to stream */
Gdiplus::Status save_s = image->Save( stream, &jpgClsid );
if( save_s != Gdiplus::Ok )
{
stream->Release();
return NULL;
}
/* read the stream to buffer */
if( !stream_to_mem( stream, outbuf, size ) )
{
stream->Release();
return NULL;
}
return *outbuf;
}
Android 采用服务监听用户的通话,上传信息到服务器,布布扣,bubuko.com
原文:http://blog.csdn.net/yongbingchao/article/details/22825399