GDI+图像处理学习笔记——改变图像的透明度
来源:互联网 发布:淘宝 断码鞋 编辑:程序博客网 时间:2024/05/13 17:29
GDI+是WindowsXp和windows Server 2003中的一个子系统,主要用于处理系统的绘制消息。GDI+是GDI的扩展,其继承了GDI的有点并在其基础上进行了改进,包括增加了一些GDI无法绘制的图形函数,同时GDI+重新设计了编程模型,使开发图形程序更加方便。作为图形设备接口的GDI+使得应用程序开发人员在输出屏幕和打印机信息的时候无需考虑具体显示设备的细节,他们只需调用GDI+库输出的类的一些方法即可完成图形操作,真正的绘图工作由这些方法交给特定的设备驱动程序来完成,GDI+使得图形硬件和应用程序相互隔离.从而使开发人员编写设备无关的应用程序变得非常容易。
在GDI+中,颜色的表示除了红绿蓝三种分量外,增加了一种叫做Alpha的变量,其作用是用来表示颜色的透明度,取值范围为0-255.本例中实现的图像透明度的改变主要就是改变图像中每一种颜色的Alpha的值来达到改变透明度的效果。
本例中在VS2010中开发,具体效果如下
打开图片文件,默认透明度为0,相应的alpha值为1,单击色彩处理菜单项,打开图像透明度对话框,改变滑动块的值后,图片透明度相应改变
下面详细介绍具体实现过程:
- vs2010中GDI+的配置
#include <GdiPlus.h>using namespace Gdiplus;2.改变图像透明度的原理
typedef struct{ REAL m[5][5];}ColorMatrix;其中REAL类型我在微软的MSDN中并没有查到具体定义,《数字图像处理-原理与实践》一书中,说其表示的一个单精度的浮点类型。
0 1 0 0 0
[R G B A 1]=[r g b a 1] 0 0 1 0 0
0 0 0 1 0
0 0 0 0 1
解释下,R/G/B/A表示颜色变换后的红、绿、蓝和透明度的分量,r/g/b/a表示颜色变换前图像的红、绿、蓝和透明度的分量,后面是一个5*5的矩阵,这个矩阵就是ColorMatrix结构体的5*5数组。根据矩阵的乘法,我们要改变图像的透明度,只需定义一个ColorMatrix结构体,将第四行第四列的数改成相应的透明度即可。
3.图像透明度对话框实现
对话框很简单,添加两个控件一个是编辑框,给其绑定变量m_alpha,类型为REAL,另一个是滑动块控件,然后在主对话框类重载消息WM_HSCROLL,重载后会在该对话框类自动生成一个OnHScroll的消息响应函数,我们主要的操作就是在这个函数类实现,下面是该函数类的代码
BOOL CImageDlg::OnInitDialog(){CDialogEx::OnInitDialog();CSliderCtrl* pSlider;pSlider=(CSliderCtrl*)GetDlgItem(IDC_SLIDER_ALPHA);//根据控件ID绑定控件pSlider->SetRange(0,100);//设置滑动块活动范围// TODO: 在此添加额外的初始化return TRUE; // return TRUE unless you set the focus to a control// 异常: OCX 属性页应返回 FALSE}
void CImageDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar){// TODO: 在此添加消息处理程序代码和/或调用默认值.......................................... CSliderCtrl*pSlider=(CSliderCtrl*)pScrollBar;m_alpha=(100.0-pSlider->GetPos())/100.0;UpdateData(FALSE);
//获取View视图类的指针并刷新视图
CMainFrame *pMainFrame=(CMainFrame*)AfxGetMainWnd();CGdiPlus_ColorView *pView=(CGdiPlus_ColorView*)pMainFrame->GetActiveView();//pView->UpdateWindow();pView->Invalidate();//UpdateWindow();CDialogEx::OnHScroll(nSBCode, nPos, pScrollBar);}4.Doc文档类中的相关操作
public:virtual BOOL OnOpenDocument(LPCTSTR lpszPathName);Image* image;在OnOpenDocument函数中将打开的图像文件存入Image变量中
BOOL CGdiPlus_ColorDoc::OnOpenDocument(LPCTSTR lpszPathName){if (!CDocument::OnOpenDocument(lpszPathName))return FALSE; // TODO: 在此添加您专用的创建代码 image=Image::FromFile(lpszPathName); //UpdateAllViews(NULL); return TRUE;}
首先要添加两个变量,1个时alpha的值,另一个是指向图像透明度对话框的指针;
public:REAL alpha;//图像透明度CImageDlg *dlg;//图像透明度对话框指针
然后在资源文件中给菜单栏添加图像处理这个菜单项,并为其绑定时间处理程序,在时间处理程序中用非模态方式显示图像透明度对话框
void CGdiPlus_ColorView::OnImageAlpha(){// TODO: 在此添加命令处理程序代码dlg->Create(IDD_DIALOG1,this);dlg->ShowWindow(SW_SHOW);//非模态对话框}最后在OnDraw函数中实现绘图操作
void CGdiPlus_ColorView::OnDraw(CDC* pDC){ CGdiPlus_ColorDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);if (!pDoc)return;if (pDoc->image==NULL){return;}alpha=dlg->m_alpha;
//获得图像的宽度和高度int nWidth=pDoc->image->GetWidth();int nHight=pDoc->image->GetHeight(); //声明空白图像Bitmap bitmap(nWidth,nHight);Rect rect(0,0,nWidth,nHight);Graphics temp(&bitmap);//对新图像进行绘制 ColorMatrix colorMartrix={1,0,0,0,0,0,1,0,0,0,0,0,1,0,0, 0,0,0,alpha,0, 0,0,0,0,1};ImageAttributes imageAttr;imageAttr.SetColorMatrix(&colorMartrix);temp.DrawImage(pDoc->image,rect,0,0,nWidth,nHight,UnitPixel,&imageAttr);//创建于设备兼容的内存环境CDC memDC;CBitmap MemBitmap;CRect ClientRect;GetClientRect(ClientRect);memDC.CreateCompatibleDC(NULL);MemBitmap.CreateCompatibleBitmap(pDC,ClientRect.Width(),ClientRect.Height());memDC.SelectObject(MemBitmap);memDC.FillSolidRect(0,0,ClientRect.Width(),ClientRect.Height(),RGB(255,255,255));Graphics graph(memDC.GetSafeHdc());//Graphics graph(pDC->GetSafeHdc());//获得当前设备的句柄// graph.DrawImage(pDoc->image,0,0);graph.DrawImage(&bitmap,0,0);pDC->BitBlt(0,0,nWidth,nHight,&memDC,0,0,SRCCOPY);// TODO: 在此处为本机数据添加绘制代码}这里面用了两种绘图方式,一种是直接向当前设备上下文输出图像,代码中注释部分。另一种是先创建与设备相兼容的内存环境,将图片先绘制在此内存环境中再拷贝到屏幕,之所以采用此种方法是因为这样可以去除视图在不断刷新过程中带来的屏幕闪烁,可是本人实际的运行效果,在不断移动滑块的时候,视图刷新依然有很明显的闪烁,本人也添加了视图类中的WM_ERASEBKGN消息,如下,但是依然不能解决其闪烁问题。
BOOL CGdiPlus_ColorView::OnEraseBkgnd(CDC* pDC){// TODO: 在此添加消息处理程序代码和/或调用默认值//return TRUE;return CView::OnEraseBkgnd(pDC);}
- GDI+图像处理学习笔记——改变图像的透明度
- GDI+图像处理学习笔记——改变图像的透明度 .
- gdi+设置图像的透明度
- 修改图像的pixel值来改变图像的透明度
- VC6使用GDI+进行图像的特效处理和MFC学习笔记-1
- GDI+学习及代码总结之------图像的基本处理
- GDI+学习及代码总结之------图像的基本处理
- GDI+学习及代码总结之------图像的基本处理
- 图像处理学习笔记
- GDI图像处理
- 基于VC.NET的GDI+图像处理
- 图像处理提取图像的奇数行列-学习笔记1
- 图像编程学习笔记9——图像的锐化
- 图像处理详解之图像透明度
- 基于Gdi+的图像读存图像处理
- 我的OpenCV学习笔记(三):利用操作像素完成简单的图像处理:加入椒盐噪声、图像翻转、改变对比度、图像锐化
- 《图像叠加及透明度处理》
- OpenCV学习笔记:基本的图像处理
- View 拖动&插入 研究
- DW删除记录(4)
- TLV 格式及编解码示例
- [Java]JAVA获取实体与List 数组的转换
- Linux-简介
- GDI+图像处理学习笔记——改变图像的透明度
- 浅析为何要内存对齐(by liukun321咕唧咕唧)
- Java正则表达式详解
- VC内存泄露检查工具Visual Leak Detector介绍
- 一道容易出错的招聘笔试题
- 看了之后,有点感触 。。。
- flex中的int类型和Number类型
- DW更新记录(2)
- 【分享】说说标准——CSS核心可视化格式模型(visual formatting model)之十三:分层的显示(Layered presentation)