利用GDI+实现gif图像背景透明
来源:互联网 发布:java. se有哪些内容 编辑:程序博客网 时间:2024/05/16 06:50
要实现将GIF图像进行透明处理,需要调用三个函数, MakeTransparent函数为将图像数据进行透明处理的函数,GetEncoderClsid为获取clsid,StreamToByte为将流转换为byte数组的函数,
这三个函数的具体代码如下:
MakeTransparent(IStream * inStream, IStream ** outStream)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
//制作透明gif
Bitmap *image=Bitmap::FromStream(inStream);
// 图象打开失败返回错误
if( image->GetLastStatus() != Ok ) {
return FALSE;
}
// 如果不是单帧的GIF则返回错误
GUID guidFormat;
Status status;
status = image->GetRawFormat( &guidFormat );
if( status != Ok || guidFormat != ImageFormatGIF ){
return FALSE;
}
if( image->GetPixelFormat() != PixelFormat8bppIndexed )
return FALSE; // GIF 格式必须为PixelFormat8bppIndexed格式
UINT nCount = 0,nFrames;
nCount = image->GetFrameDimensionsCount();
GUID* pDimensionIDs = new GUID[nCount];
image->GetFrameDimensionsList(pDimensionIDs, nCount);
nFrames = image->GetFrameCount(&pDimensionIDs[0]);
delete []pDimensionIDs;
// 不是单帧的GIF则返回
if( nFrames != 1 ){
return FALSE;
}
// 通过改变pallete来设置透明色
BOOL bRet = FALSE;
UINT palSize = image->GetPaletteSize();
COLORREF transColor;
transColor=RGB(255,255,255);
if( palSize > 0 )
{
ColorPalette* palette = (ColorPalette*)malloc(palSize);
status = image->GetPalette( palette , palSize );
for( UINT i =0; i<palette->Count; ++i ){
if( (palette->Entries[i] & 0x00FFFFFF ) == transColor)
palette->Entries[i] &= 0x00FFFFFF;
else
palette->Entries[i] |= 0xFF000000;
}
palette->Flags |= PaletteFlagsHasAlpha;
// 创建位图对象
Bitmap bitmap(image->GetWidth(),image->GetHeight(),PixelFormat8bppIndexed) ;
if( bitmap.GetLastStatus() != Ok ){
free(palette); palette = NULL;
return FALSE;
}
status = bitmap.SetPalette( palette );
// 将image中的点的索引拷贝到bitmap中
BitmapData bitmapData,imageData;
Rect rect(0, 0, image->GetWidth(), image->GetHeight());
status = bitmap.LockBits( &rect,ImageLockModeWrite,PixelFormat8bppIndexed,&bitmapData);
if( status == Ok )
{
status = image->LockBits( &rect,ImageLockModeRead,PixelFormat8bppIndexed,&imageData );
if( status == Ok )
{
BYTE *pixels,*pixelsNew;
if (imageData.Stride > 0)
pixels = (BYTE*) imageData.Scan0;
else
pixels = (BYTE*) imageData.Scan0 + imageData.Stride*(image->GetHeight()-1);
UINT stride = abs(imageData.Stride);
pixelsNew = (BYTE*)bitmapData.Scan0;
for(UINT row = 0; row < image->GetHeight(); ++row)
{
for(UINT col = 0; col < image->GetWidth(); ++col)
{
UINT i8BppPixel = row * stride + col;
pixelsNew[i8BppPixel] = pixels[i8BppPixel];
}
}
CLSID gifClsid;
int ret=GetEncoderClsid( L"image/gif",&gifClsid );
if( ret != -1 )
bRet = bitmap.Save(*outStream , &gifClsid)==Ok;
image->UnlockBits( &imageData );
}
bitmap.UnlockBits( &bitmapData );
}
free(palette); palette = NULL;
}
return S_OK;
}
GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
UINT num= 0;
UINT size= 0;
ImageCodecInfo* pImageCodecInfo= NULL;
GetImageEncodersSize(&num, &size);
if(size== 0)
{
return -1;
}
pImageCodecInfo= (ImageCodecInfo*)(malloc(size));
if(pImageCodecInfo== NULL)
{
return -1;
}
GetImageEncoders(num, size, pImageCodecInfo);
for(UINT j=0; j< num; ++j)
{
if(wcscmp(pImageCodecInfo[j].MimeType, format)== 0)
{
*pClsid= pImageCodecInfo[j].Clsid;
free(pImageCodecInfo);
return j;
}
}
free(pImageCodecInfo);
return -1;
}
StreamToByte(IStream *InStream, BYTE* ImageBuff, DWORD* dwSize)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
//获得与流对应的内存句柄
HGLOBAL hMem;
GetHGlobalFromStream(InStream,&hMem);
DWORD streamSize =GlobalSize(hMem);
if (ImageBuff == NULL || *dwSize < streamSize)
{
*dwSize = streamSize;
return S_OK;
}
BYTE *pbyBmp = (BYTE *)GlobalLock(hMem);
memcpy_s(ImageBuff,*dwSize,pbyBmp, streamSize);
::GlobalUnlock(hMem);
return S_OK;
}
调用这个三个函数实现图像背景透明处理的操作代码如下:
//位图保存到流
CLSID encoderClsid;
psl->GetEncoderClsid(L"image/gif",&encoderClsid);
IStream *pStream = NULL;
HRESULT iRet = CreateStreamOnHGlobal(NULL,TRUE,&pStream);
Status sRet = pBitmap->Save(pStream,&encoderClsid,NULL);
//生成透明印章图像
IStream *bStream = NULL;
HRESULT bRet = CreateStreamOnHGlobal(NULL,TRUE,&bStream);
BOOL mret=psl->MakeTransparent(pStream,&bStream);
//将流转换成字节数组
BYTE * picBuff=NULL;
DWORD picBuffSize = 0;
BOOL stRet=psl->StreamToByte(bStream,picBuff,&picBuffSize);
picBuff = new BYTE[picBuffSize + 1];
memset(picBuff, 0x00, picBuffSize+1);
stRet=psl->StreamToByte(bStream,picBuff,&picBuffSize);
本代码经实际操作,在WIN7下可行,但在xp下仍会显示不透明背景
- 利用GDI+实现gif图像背景透明
- 设置Gif背景透明
- 利用photoshopcs6将gif格式图片变为背景透明
- .NET的GDI+实现背景的透明处理
- 利用GDI+实现BMP、JPEG、GIF图像格式的转换
- 利用GDI+显示GIF动画
- 用Fireworks制作背景透明GIF图片
- cximage 进行gif 背景透明处理
- 在vc里使gif背景透明
- GDI+ 将图片背景设为透明
- GDI+ 画透明背景的字
- MFC PNG作背景 透明边框GDI+
- GDI透明动画(多背景移动
- 利用CxImage实现编解码Gif图像代码举例
- Gif合成透明PNG变成黑色背景GIF问题解决
- C# 用GDI在图片上写字实现lable透明背景
- 利用GDI plus 播放GIF图片
- CorelDraw 9导出透明GIF图像
- ASP.NET__颗粒归仓
- ASIHTTPRequest多次重复请求的问题
- Java---14---多线程---synchronized 同步函数
- sudo: /etc/sudoers is mode 0777, should be 0440终极解决之道
- Android 开发 之 JNI入门 - NDK从入门到精通
- 利用GDI+实现gif图像背景透明
- 谭浩强C语言入门经典l例题292页——15
- 深入探索透视纹理映射(下)
- SharePoint开发 - 自定义导航菜单(三)附其他代码
- php const和define的区别(php类中如何定义常量)
- Win7 64bit 安装VisualSVN出现报错:Servic 'VisualSVN Server' failed to start.解决办法
- spring 集成junit做测试
- 重构方法 mark
- 非阻塞Connect对于select时应注意问题