如何使用GDI+在缓冲区(内存)中转换图像类型
//datecompress 图片的质量(只有在转换成jpg有效) //nSize 图片缓冲区的大小(要转的图片数据大小) //PicDate 这是一个指针,指向你的图片的 unsigned int size=0;//得到图像大小 BYTE* buffers;//存储图像数据的缓冲 Bitmap *image = CreateBitmapFromMemory(PicDate,nSize); //把你的图像数据加载入内存 SaveBitmapToMemory(image,(void **)&buffers,&size,CodecIndex,datecompress); //转换成你要的类型,从buffers获取 //说明:CodecIndex取值0-4,分别对应转换为jpg、bmp、gif、png、tiff格式,当为0时,参数datecompress有用,表示转换jpg的质量,取值0-100,数值越小,压缩比越大。 //这里是你的代码 ..... //这里是你的代码 delete image; delete buffers; //把这些代码放入声明 Bitmap* CreateBitmapFromMemory(const void *buf, size_t size); void* SaveBitmapToMemory(Bitmap *image, void **outbuf, size_t *size, size_t CodecIndex, ULONG quality); //把这些代码加入到你的源文件最后 int A2U(const char* szA,wchar_t* szU,size_t cnt) { return MultiByteToWideChar (CP_ACP, 0, szA, -1, szU, cnt) ; } int GetEncoderClsid(LPCTSTR szFormat, CLSID* pClsid) // help { UINT j; UINT num = 0; // number of image encoders UINT size = 0; // size of the image encoder array in bytes ImageCodecInfo* pImageCodecInfo = NULL; GetImageEncodersSize(&num, &size); if(size == 0) return -1; // Failure pImageCodecInfo = (ImageCodecInfo*)(malloc(size)); if(pImageCodecInfo == NULL) return -1; // Failure GetImageEncoders(num, size, pImageCodecInfo); #ifndef UNICODE wchar_t wszFormat[32]; A2U(szFormat,wszFormat,32); for(j = 0; j < num; ++j) { if( wcscmp(pImageCodecInfo[j].MimeType, wszFormat) == 0 ) #else for(j = 0; j < num; ++j) { if( wcscmp(pImageCodecInfo[j].MimeType, szFormat) == 0 ) #endif { *pClsid = pImageCodecInfo[j].Clsid; free(pImageCodecInfo); return j; // Success } } free(pImageCodecInfo); return -1; // Failure } 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; } Bitmap* CreateBitmapFromMemory(const void *buf, size_t size) { IStream *stream = NULL; 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 ); stream->Revert(); return NULL; } /* get the IStream from the global object */ if( CreateStreamOnHGlobal( global, true, &stream ) != S_OK ) { GlobalFree( global ); stream->Revert(); return NULL; } /* create the image from the stream */ Bitmap *image = Bitmap::FromStream( stream, FALSE ); //stream->Release(); stream->Revert(); stream = NULL; /* I suppose when the reference count for stream is 0, it will GlobalFree automatically. The Image maintain the object also.*/ return image; } 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; } 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(); GlobalFree(global); return *outbuf; }
至于如何调用GDI+,在我博客中有另外说明