使用GDI+保存带Alpha通道的图像
bool ImageUtil :: CreateGdiplusBmpFromHBITMAP_Alpha ( HBITMAP hBmp , Gdiplus :: Bitmap ** bmp )
{
BITMAP bitmap ;
GetObject ( hBmp , sizeof ( BITMAP ), & bitmap );
if ( bitmap . bmBitsPixel != 32)
{
return false ;
}
Gdiplus :: Bitmap * pWrapBitmap = Gdiplus :: Bitmap :: FromHBITMAP ( hBmp , NULL );
if ( pWrapBitmap )
{
Gdiplus :: BitmapData bitmapData ;
Gdiplus :: Rect rcImage (0, 0, pWrapBitmap -> GetWidth (), pWrapBitmap -> GetHeight ());
pWrapBitmap -> LockBits (& rcImage , Gdiplus :: ImageLockModeRead , pWrapBitmap -> GetPixelFormat (), & bitmapData );
* bmp = new Gdiplus :: Bitmap ( bitmapData . Width , bitmapData . Height , bitmapData . Stride , PixelFormat32bppARGB , ( BYTE *) bitmapData . Scan0 );
pWrapBitmap -> UnlockBits (& bitmapData );
delete pWrapBitmap ;
return true ;
}
return false ;
}
Gdiplus :: Bitmap * ImageUtil :: CreateBitmapFromHBITMAP ( IN HBITMAP hBitmap )
{
BITMAP bmp = { 0 };
if ( 0 == GetObject ( hBitmap , sizeof ( BITMAP ), ( LPVOID )& bmp ) )
{
return FALSE ;
}
// Although we can get bitmap data address by bmp.bmBits member of BITMAP
// which is got by GetObject function sometime,
// we can determine the bitmap data in the HBITMAP is arranged bottom-up
// or top-down, so we should always use GetDIBits to get bitmap data.
BYTE * piexlsSrc = NULL ;
LONG cbSize = bmp . bmWidthBytes * bmp . bmHeight ;
piexlsSrc = new BYTE [ cbSize ];
BITMAPINFO bmpInfo = { 0 };
// We should initialize the first six members of BITMAPINFOHEADER structure.
// A bottom-up DIB is specified by setting the height to a positive number,
// while a top-down DIB is specified by setting the height to a negative number.
bmpInfo . bmiHeader . biSize = sizeof ( BITMAPINFOHEADER );
bmpInfo . bmiHeader . biWidth = bmp . bmWidth ;
bmpInfo . bmiHeader . biHeight = bmp . bmHeight ; // 正数,说明数据从下到上,如未负数,则从上到下
bmpInfo . bmiHeader . biPlanes = bmp . bmPlanes ;
bmpInfo . bmiHeader . biBitCount = bmp . bmBitsPixel ;
bmpInfo . bmiHeader . biCompression = BI_RGB ;
HDC hdcScreen = CreateDC ( L "DISPLAY" , NULL , NULL , NULL );
LONG cbCopied = GetDIBits ( hdcScreen , hBitmap , 0, bmp . bmHeight ,
piexlsSrc , & bmpInfo , DIB_RGB_COLORS );
DeleteDC ( hdcScreen );
if ( 0 == cbCopied )
{
delete [] piexlsSrc ;
return FALSE ;
}
// Create an GDI+ Bitmap has the same dimensions with hbitmap
Bitmap * pBitmap = new Bitmap ( bmp . bmWidth , bmp . bmHeight , PixelFormat32bppPARGB );
// Access to the Gdiplus::Bitmap's pixel data
BitmapData bitmapData ;
Rect rect (0, 0, bmp . bmWidth , bmp . bmHeight );
if ( Ok != pBitmap -> LockBits (& rect , ImageLockModeRead ,
PixelFormat32bppPARGB , & bitmapData ) )
{
delete ( pBitmap );
return NULL ;
}
BYTE * pixelsDest = ( BYTE *) bitmapData . Scan0 ;
int nLinesize = bmp . bmWidth * sizeof ( UINT );
int nHeight = bmp . bmHeight ;
// Copy pixel data from HBITMAP by bottom-up.
for ( int y = 0; y < nHeight ; y ++ )
{
// 从下到上复制数据,因为前面设置高度时是正数。
memcpy_s (
( pixelsDest + y * nLinesize ),
nLinesize ,
( piexlsSrc + ( nHeight - y - 1) * nLinesize ),
nLinesize );
}
// Copy the data in temporary buffer to pBitmap
if ( Ok != pBitmap -> UnlockBits (& bitmapData ) )
{
delete pBitmap ;
}
delete [] piexlsSrc ;
return pBitmap ;
}
bool ImageUtil::SavePng( HBITMAP hBmp, LPCTSTR lpszFilePath )
{
DIBSECTION dibsection;
int nBytes = ::GetObject( hBmp, sizeof( DIBSECTION ), &dibsection ); Gdiplus::Bitmap* bitmap = 0; if(nBytes != sizeof(DIBSECTION) || dibsection.dsBm.bmBitsPixel != 32)
{
// Bitmap with plate or non-ARGB(32bpp)
bitmap = Gdiplus::Bitmap::FromHBITMAP(hBmp);
}
else
{
int width, height, bits_per_pixel, pitch;
LPVOID bits; width = dibsection.dsBmih.biWidth;
height = abs( dibsection.dsBmih.biHeight );
bits_per_pixel = dibsection.dsBmih.biBitCount;
pitch = (((width*bits_per_pixel)+31)/32)*4; //计算行宽,四字节对齐 ATL::CImage::ComputePitch
bits = dibsection.dsBm.bmBits; if( dibsection.dsBmih.biHeight > 0 )
{
bits = LPBYTE( bits )+((height-1)*pitch);
pitch = -pitch;
} bitmap = new Gdiplus::Bitmap(width, height, pitch, PixelFormat32bppARGB, static_cast< BYTE* >(bits ));
} bool ret = false;
CLSID clsid = GetGdiplusEncoderClsid(NULL, &Gdiplus::ImageFormatPNG);
if(clsid != CLSID_NULL)
{
ret = (Gdiplus::Ok == bitmap->Save(lpszFilePath, &clsid, NULL));
}
delete bitmap;
return ret;
}
使用GDI+保存带Alpha通道的图像的更多相关文章
- 使用GDI+保存带Alpha通道的图像(续)
之前结合网上的一些代码及ATL::CImage的实现,自己写了一个将HBITMAP以PNG格式保存到文件到函数.见上一篇日记. 不过,后来换了个环境又发现了问题,昨天和今天上午把<Windows ...
- 带Alpha通道的色彩叠加问题
css3的rgba色彩模式.png/gif图片的alpha通道.canvas的rgba色彩模式.css3的阴影.css3的opacity属性等等,这些应用在网页中,有意无意间,我们的页面多了许多半透明 ...
- Unity 播放 带 alpha 通道的视频(Video Player组件)
孙广东 2017.6.18 http://blog.csdn.NET/u010019717 通常是 .webm类型文件!!!!! 你可以下载这个文件到本地: Http://tsubakit1.s ...
- 如何基于纯GDI实现alpha通道的矢量和文字绘制
今天有人在QQ群里问GDI能不能支持带alpha通道的线条绘制? 大家的答案当然是否定的,很多人推荐用GDI+. 一个基本的图形引擎要包括几个方面的支持:位图绘制,文字绘制,矢量绘制(如矩形,线条). ...
- 什么是Alpha通道?
图像处理(Alpha通道,RGB,...)祁连山(Adobe 系列教程)****的UI课程 一个也许很傻的问题,在图像处理中alpha到底是什么? Alpha通道是计算机图形学中的术语,指的是特别的 ...
- Alpha通道
Alpha通道是计算机图形学中的术语,指的是特别的通道,意思是“非彩色”通道,主要是用来保存选区和编辑选区.真正让图片变透明的不是Alpha 实际是Alpha所代表的数值和其他数值做了一次运算 为 ...
- ImagXpress中如何修改Alpha通道方法汇总
ImagXpress支持处理Alpha通道信息来管理图像的透明度,Alpha通道支持PNG ,TARGA和TIFF文件,同时还支持BMP和ICO文件.如果说保存的图像样式不支持Alpha通道,就将会丢 ...
- PIE SDK Alpha通道数据渲染
1. 功能简介 在计算机图形学中,一个RGB颜色模型的真彩图形,用由红.绿.蓝三个色彩信息通道合成的,每个通道用了8位色彩深度,共计24位,包含了所有彩色信息.为实现图形的透明效果,采取在图形文件的 ...
- 使用opencv为没有透明通道的图像加入透明通道
在图像处理中,我们经常需要处理带透明通道的图片,比如为图片或视频添加水印,为图片或视频添加字幕.贴图等.然而,我们的素材图片未必总是带有透明通道.比如,素材的背景本该透明的地方,却是黑色和白色.有时, ...
随机推荐
- hdu 6040 Hints of sd0061(stl: nth_element(arr,arr+k,arr+n))
Hints of sd0061 Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others ...
- Linux 去重 先sort再uniq
从uniq命令的帮助信息中可以看到,该命令只过滤相邻的重复行. 如果要去掉所有重复行,需要先排序,或者使用uniq -u $ uniq --h Usage: uniq [OPTION]... [INP ...
- SQL Server插入或修改数据是中文乱码的问题
SQL Server中乱码解决方案: 在Sql Server2005英文版中,如果未对Varchar类型的字段进行设置,那么很多朋友会发现向数据库中插入记录时,如果对应的varchar类型字段 的值为 ...
- Ubuntu16.04 --> 14.04
从16到14 自认为14是比较稳定的.从安装依赖上说. 14安装应用 更多参见[请直接拉到"华丽丽的分割线"下面] Java9 注意,添加源的时候先把lantern打开!!! 添加 ...
- Adobe Flash Builder 4.6 Premium 安装破解
1.到Adobe官网下载FlashBuilder 4.6,有简体中文版: 语言:简体中文(Simplified)http://trials3.adobe.com/AdobeProducts/FLBR/ ...
- ios逆向工程-静态分析
最近在学习IOS逆向工程,查看网络上的资料也不是太多,边学边总结一下. 首先学习资料: 念茜(大神)的博客: http://nianxi.net <ios应用逆向工程 分析与实战> --- ...
- div横排放置对齐问题;block,inline,inline-block区别
1.左右两个div都设置为float:left,如果右边div没有设置宽度,右边div的宽度会根据div里的内容自动调整. 缺点:不易控制 2.只有左侧div设置为float:left,右侧div设置 ...
- Codeforces 280C Game on tree【概率DP】
Codeforces 280C Game on tree LINK 题目大意:给你一棵树,1号节点是根,每次等概率选择没有被染黑的一个节点染黑其所有子树中的节点,问染黑所有节点的期望次数 #inclu ...
- 在iOS中使用ZBar扫描二维码
最近在做的项目中需要用到二维码扫描功能,之前在Android中使用过ZXing识别二维码,ZXing也有对应的iOS版本,经过了解,ZBar也是一个常用的二维码识别软件,并分别提供了iOS和Andro ...
- 《DSP using MATLAB》示例Example6.2
2017年了,阳历新年都11号了,已从外地回到家乡,依然苦逼的生活…… 接着写读书(Digital Signal Processing using MATLAB)笔记吧 代码: b = [1 -3 1 ...