`
happmaoo
  • 浏览: 4548330 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

---===浅谈位图的淡入淡出和渐隐===---

阅读更多
<iframe align="top" marginwidth="0" marginheight="0" src="http://www.zealware.com/csdnblog01.html" frameborder="0" width="728" scrolling="no" height="90"></iframe>

浅谈位图的淡入淡出和渐隐<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

成都电子科技大学

朱宁

在许多游戏和屏幕保护程序中,我们都可以发现位图的淡入淡出和渐隐(一幅图象渐渐的消失于另一幅图象中)的应用。如何实现这些效果呢?

windows(GDI)环境下,实现位图的淡入淡出和渐隐的方法有三种:1.调色板动画;2.模式画刷;3.动画法。其中,第一种方法速度很快,但只能用于256色的图形,而且不易实现渐隐效果。第二种方法实现比较简单,但是主观效果不及其余两种。第三种方法的效果很好,但速度要稍慢一些。由于现在已经很难得到质量较高的256色图片,加之目前几乎所有的显卡均支持高彩和真彩模式,所以不推荐采用第一种方法。下面介绍后两种方法在Visual C++编程环境下的实现。

一:模式画刷法:

CDC类的BitBlt(...),MaskBlt(...),以及WIN32API ::StretchDIBits(...)函数均支持三元ROP(Raster Operation)操作,即由源,模式画刷(pattern brush)和目的区域原有的图形经一定的逻辑运算而形成最终的输出图形。所以,通过改变模式画刷的图案,辅以一定的ROP操作,就可以形成一些特殊的效果。

首先,要准备若干个8*8的单色位图,作为模式画刷的模板。单色位图中应只含有黑白两种颜色的像素,每一个位图中两种像素的比例和形状将决定显示的效果,通常我们由一个全黑的位图开始,逐渐增加白色像素的比例,最后一幅位图全部由白色象素组成。

这些位图制作好以后,将它们Import入工程,命名为IDB_PATTERN1、IDB_PATTERN2 ... ... 调用CBitmap::LoadBitmap(...)函数将其选入对应的CBitmap对象,然后调用CBrush::CreatePatternBrush(...)制作模式画刷。

有了合适的模式画刷以后,还需要设定我们所需的ROP码,对于淡入操作,要求将源位图与模式画刷的反依次相与。对于淡出操作,要求将当前显示区域的位图与模式画刷依次相与。对于渐隐,我们需要把原位图与模式画刷相与后,把这个结果和当前显示区域的位图和画刷的镜象(原画刷的非)相与的结果相或。依次改变画刷,就可以得到渐隐的效果。这些操作的ROP码,MFC中并没有对应的预定义宏,但我们可以通过计算得到它,在Visual C++ 5.0 的在线文档“Ternary Raster Operations”中,详细介绍了计算方法。最终我们得到淡入、淡出操作的ROP码分别为000C0324、0x00A000C9。渐隐操作的ROP码是0x00AC0744。为了形成完整的动画效果,我们需要设置一个定时器来自动的执行这一系列的操作。

下面用一个简单的例子说明模式画刷法的实现:

1:建立一个基于对话框的项目,命名为PatternDemo.

2:删除对话框上的“Todo:...”注释,并增加一个按纽,命名为“DEMO”

3:为DEMO按纽加入对应的事件句柄OnDEMO(...).

4:在CPatternDemo中加入私有成员变量如下:

CDC *pdc;

CDC memDC;

CBitmap bmp;

CBrush brush[8];

UINT counter;

UINT mode;

UINT onrun;

5:用VC自带的位图编辑器,按上文要求编辑8个8*8像素的单色位图,命名为IDB_PATTERN1...IDB_PATTERN8。

6:Import两个100*100像素的真彩bmp图片,命名为IDB_BMPSOURCE1和IDB_BMPSOURCE2。

7:使用ClassWizard为CPatternDemoDlg加入WM_CREATE的消息响应函数OnCreate(...),并在其中添加如下代码:

...

for(int i=0;i

{

bmp.LoadBitmap(IDB_PATTERN1+i);

brush[i].CreatePatternBrush(&bmp);

bmp.DeleteObject();

}

...

8:在CPatternDemoDlg::OnDEMO(...)函数中添加如下代码:

...

if(!onrun)

{

pdc=GetDC();

pdc->SetBkColor(RGB(0,0,0));

pdc->SetTextColor(RGB(255,255,255));

pdc->FillSolidRect(0,0,100,100,RGB(0,0,0));

memDC.CreateCompatibleDC(pdc);

bmp.LoadBitmap(IDB_BMPSOURCE1);

memDC.SelectObject(&bmp);

bmp.DeleteObject();

mode=1;

counter=0;

SetTimer(1,200,NULL);

onrun=1;

}

...

9:使用ClassWizard为CPatternDemoDlg加入WM_TIMER的消息响应函数OnTimer(...),并在其中添加如下代码:

...

if(mode==1)

{

if(counter>7)

{

mode=2;

counter=0;

return;

}

pdc->SelectObject(&brush[counter]);

pdc->BitBlt(0,0,100,100,&memDC,0,0,0x000C0324);

counter++;

}

if(mode==2)

{

if(counter>7)

{

mode=3;

counter=0;

return;

}

if(counter==0)

{

bmp.LoadBitmap(IDB_BMPSOURCE2);

memDC.SelectObject(&bmp);

bmp.DeleteObject();

}

pdc->SelectObject(&brush[counter]);

pdc->BitBlt(0,0,100,100,&memDC,0,0,0x00AC0744);

counter++;

}

if(mode==3)

{

if(counter>7)

{

memDC.DeleteDC();

bmp.DeleteObject();

KillTimer(1);

onrun=0;

return;

}

pdc->SelectObject(&brush[counter]);

pdc->BitBlt(0,0,100,100,NULL,0,0,0x00A000C9);

counter++;

}

...

9:在CPatternDemoDlg::CpatternDemoDlg()中加入:

...

onrun=0;

...

10: 使用ClassWizard为CPatternDemoDlg加入WM_DESTORY的消息响应函数OnDestory(...),并在其中添加如下代码:

...

memDC.DeleteDC();

KillTimer(1);

...

编译运行该项目,可以看到第一幅图象从背景中渐渐的浮现出来,随后,又渐渐地隐入第二幅图象之中,接着,第二幅图象又慢慢地消失于背景中。

动画法

这种方法是利用直接操作位图的数据来实现的,可以实现像素颜色的平滑变化,视觉效果可以做的很好,因此,这种方法在屏保中的应用非常多。

首先,我们必须了解bmp图形的结构。一个bmp图形由两个部分组成,即文件头和数据区,文件头存放bmp图形的大小、格式等信息,数据区存放bmp图形各个像素的颜色信息。对于24位真彩色的bmp来说,文件头的大小为54个字节,前14个字节对应VC中定义的BITMAPFILEINFO结构,后40个字节对应BITMAPINFOHEADER结构。我们把bmp数据区的数据读出,经过一定的运算,再利用WIN32API::StretchDIBits(...)函数直接输出到显示DC上,就可以实现一些特技效果。

下面让我们分步去实现一个全屏幕的演示程序:

1:生成一个基于对话框的项目,命名为F1:

2:删除F1Dlg.h、F1Dlg.h和F1.cpp中与其相关的所有代码。

3:在项目中添加一个基类为generic Cwnd的新类,命名为CW.

4:为CW类添加如下私有成员变量:

//////////////////////

UINT y_offset;

UINT x_offset;

UINT stage;

BYTE* p3;

BYTE * p2;

BYTE * p1;

BITMAPINFOHEADER header;

HGLOBAL hlb1;

HGLOBAL hlb2;

HGLOBAL hlb3;

UINT start;

UINT counter;

////////////////////////

并在W.h的顶部加入宏定义 #define BMP_SIZE 192000

5:为CW添加Create(...)虚函数,WM_CREATE,WM_TIMER,WM_PAINT,WM_DESTORY,WM_LBUTTONDOWN的消息句柄,接受缺省的函数名称。

6:删除CW::Create(...)中的原有代码,用以下代码替换:

/////////////////////////

LPCTSTR m_lpszCN;

m_lpszCN = AfxRegisterWndClass(CS_BYTEALIGNCLIENT,

::LoadCursor(AfxGetResourceHandle(),

MAKEINTRESOURCE(IDC_NULLCORSOR)));

return CWnd::CreateEx(WS_EX_TOPMOST,m_lpszCN, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext);

//////////////////////////

7: 删除CF1App:: InitInstance()中#endif以后的所有代码,用以下代码代替:

///////////////////////////

int cx=GetSystemMetrics(SM_CXSCREEN);

int cy=GetSystemMetrics(SM_CYSCREEN);

CRect rectDefault(0,0,cx,cy);

m_pMainWnd=new CW();

m_pMainWnd->Create(NULL, _T("Hello World!"), WS_VISIBLE|WS_POPUP, rectDefault,NULL,NULL);

return TRUE;

///////////////////////////

8:在CW::OnCreate(...)函数中加入如下代码:

/////////////////////////////

counter=0;

int cx=GetSystemMetrics(SM_CXSCREEN);

int cy=GetSystemMetrics(SM_CYSCREEN);

x_offset=(cx-640)/2;

y_offset=(cy-400)/2;

/////////////////////////////

9: 在CW::OnDestroy()函数中加入如下代码:

////////////////////////////////

KillTimer(1);

GlobalFree(hlb1);

GlobalFree(hlb2);

GlobalFree(hlb3);

/////////////////////////////

10: 在CW:: OnLButtonDown(...)函数中加入如下代码:

//////////////////////////////

SendMessage(WM_CLOSE);

//////////////////////////////

11: 在CW:: OnLButtonDown(...)函数中加入如下代码:

/////////////////////////////

CPaintDC dc(this);

dc.FillSolidRect(0,0,800,600,RGB(0,0,0));

dc.SetTextColor(RGB(200,0,0));

if(!start) return;

CFile f1,f2;

f1.Open("bmp1.bmp",CFile::modeRead);

f2.Open("bmp2.bmp",CFile::modeRead);

f1.Seek(14,CFile::begin);

f1.Read(&header,40);

f2.Seek(54,CFile::begin);

hlb1=GlobalAlloc(GMEM_MOVEABLE,BMP_SIZE);

p1=(BYTE*)GlobalLock(hlb1);

p1=(BYTE*)malloc(BMP_SIZE);

f1.ReadHuge(p1,BMP_SIZE);

GlobalUnlock(hlb1);

hlb2=GlobalAlloc(GMEM_MOVEABLE,BMP_SIZE);

p2=(BYTE*)GlobalLock(hlb2);

f2.ReadHuge(p2,BMP_SIZE);

GlobalUnlock(hlb2);

hlb3=GlobalAlloc(GMEM_MOVEABLE,BMP_SIZE);

p3=(BYTE*)GlobalLock(hlb3);

GlobalUnlock(hlb3);

f1.Close();

f2.Close();

stage=1;

SetTimer(1,100,NULL);

start=0;

///////////////////////////

12: 在CW:: OnTimer(...)函数中加入如下代码:

///////////////////////////

if(stage==1)

{

if(counter++>63)

{

stage=2;

counter=0;

return;

}

for(int i=0;i<bmp_size></bmp_size>

p3[i]=counter*p1[i]/64;

::StretchDIBits(GetDC()->m_hDC,x_offset,y_offset,640,400,0,0,320,200,p3,

((BITMAPINFO*)(&header)),NULL,SRCCOPY);

}

if(stage==2)

{

if(counter++>63)

{

stage=3;

counter=0;

return;

}

for(int i=0;i<bmp_size></bmp_size>

p3[i]=(64-counter)*p1[i]/64+counter*p2[i]/64;

::StretchDIBits(GetDC()->m_hDC,x_offset,y_offset,640,400,0,0,320,200,p3,

((BITMAPINFO*)(&header)),NULL,SRCCOPY);

}

if(stage==3)

{

if(counter++>63)

{

KillTimer(1);

SendMessage(WM_CLOSE);

return;

}

for(int i=0;i<bmp_size></bmp_size>

p3[i]=(64-counter)*p2[i]/64;

::StretchDIBits(GetDC()->m_hDC,x_offset,y_offset,640,400,0,0,320,200,p3,

((BITMAPINFO*)(&header)),NULL,SRCCOPY);

}

//////////////////////////////////

13:最后,将两个分辨率为320*200的24bitBMP拷入工程所在的目录中,分别命名为1.bmp和2.bmp. 编译运行程序,可以看到在黑色的背景中,第一幅图象(1.bmp)由暗渐渐变亮,当它完全出现后,第二幅图象(2.bmp)从第一幅图象中慢慢的浮现出来。当第二幅图象完全取代第一幅后,它的亮度又逐渐减小,最终消失在黑色的背景中。与模式画刷法不同,这些过渡非常平滑。



Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=5682


分享到:
评论

相关推荐

    位图的Alpha淡入淡出显示示例代码.zip_Alpha_位图_位图 淡入淡出_位图显示_淡入淡出

    位图的Alpha淡入淡出显示技术在计算机图形学中是一种常见的效果,它涉及到透明度控制,使得图像能够平滑地融入或淡出背景。在Windows编程中,尤其是在使用MFC(Microsoft Foundation Classes)框架时,这个功能通常...

    位图淡入淡出显示的源代码

    位图淡入淡出显示是一种视觉效果,常用于软件界面中的图像过渡,为用户提供更平滑、更优雅的用户体验。在计算机图形学中,这种效果通常通过调整图像的透明度来实现,即调整每个像素的Alpha通道值。Alpha通道是颜色的...

    实现位图淡入淡出显示的代码(13KB)

    在这个例子中,可能有一个自定义的控件(如AlphaCtrl.cpp和AlphaCtrl.h所指)用于显示位图并处理淡入淡出效果。控件的创建、更新和消息处理都涉及Windows消息机制,这通常需要理解如CreateWindow、UpdateWindow和WM_...

    实现位图的淡入淡出显示

    在实现位图淡入淡出时,我们通常会用到GDI中的位图操作函数和Alpha混合技术。 1. **位图加载与显示**:使用`LoadImage()`函数从文件加载位图资源,然后创建一个`CBitmap`对象。接下来,创建一个`CDC`对象以准备绘制...

    窗口淡入淡出,渐隐渐显。

    本教程将详细讲解如何在VC2008环境下利用MFC实现窗口的淡入淡出效果,即所谓的“渐隐渐显”功能。 首先,我们需要了解的是窗口的基本操作。在MFC中,`CWnd`类是所有窗口类的基础,它包含了创建、显示、移动和销毁...

    位图的Alpha淡入淡出显示

    位图的Alpha淡入淡出显示是计算机图形学中的一个重要概念,主要应用于图像的透明度控制,使得图像能够平滑地融入背景或者与其他图像融合。在GUI(图形用户界面)设计、游戏开发以及多媒体应用中,这种效果被广泛应用...

    前端HTML----CSS动画特效

    淡入:fadeIn 翻转进入:flipInY 中心弹入:bounceIn 中心放大:zoomIn 翻转进入:rollIn 光速进入:lightSpeedIn 移入,从左向右:fadeInLeft 移入,从上向下:fadeInDown 移入,从右向左:fadeInRight 移入,从...

    js实现图片淡入淡出

    在JavaScript和jQuery的世界里,实现图片的淡入淡出效果是一项常见的需求,尤其在网页动态展示和动画设计中。这个主题主要围绕如何使用jQuery库来创建一个简单的图片切换功能,让图片在显示和隐藏时产生平滑的过渡...

    位图的淡入淡出显示 透明图片!

    位图的淡入淡出显示和透明处理是计算机图形学中的常见技术,广泛应用于各种界面设计和动画效果中。在Windows编程中,我们通常使用GDI(Graphics Device Interface)或GDI+来处理这些功能。这里我们将深入探讨如何...

    WPF页面淡出淡入切换效果

    在Windows Presentation Foundation (WPF) 中,开发人员可以利用丰富的动画功能来实现各种炫酷的用户界面效果,其中就包括页面之间的淡出淡入切换。这种效果能够为应用程序增添流畅和专业的视觉体验,提高用户的交互...

    js_图片淡入淡出效果_图片淡进淡出

    淡入淡出效果是通过改变图片的透明度(opacity)来实现的,通常结合CSS和JavaScript来完成。CSS用于设置初始样式,JavaScript则负责控制动画的执行。 1. **HTML结构**:创建一个div元素作为图片容器,每个图片作为...

    淡入淡出 + 宽高缩放 轮播图

    使用uniapp写的,把标签换成div和span 也能在vue项目上跑, 不管是uniapp还是vue,代码逻辑是一样的,只是html上标签的不同,在csdn没有搜到想要的demo,然后自己写好了一个demo分享出来

    位图的淡入淡出.rar

    在VC++(Visual C++)环境中实现位图的淡入淡出功能,需要理解一些基本的图形处理原理和编程技巧。 首先,我们需要了解位图的基本概念。位图是由像素组成的,每个像素有自己的颜色信息,当这些像素组合在一起时就...

    位图的淡入淡出显示

    位图的淡入淡出显示是一种常见的视觉效果,在软件界面设计和图像处理中广泛应用。它通过逐渐改变位图的透明度来实现图像的平滑过渡,使得一个图像逐渐消失,另一个图像随之出现,给人以柔和且专业的视觉体验。在...

    ffmpeg渐隐渐显草稿-修改图片路径即可

    在这个特定的场景中,"ffmpeg渐隐渐显草稿-修改图片路径即可" 提供了一个基础的实现,帮助用户通过FFmpeg实现图片的渐隐渐现效果,这在创建影集或动态幻灯片时非常有用。下面我们将深入探讨如何使用FFmpeg来实现这一...

    图片淡入淡出

    在计算机图形学和网页设计领域,图片淡入淡出是一种常见的视觉效果,它能为用户带来平滑且吸引人的过渡体验。这种效果通常用于展示一系列图片或者在页面加载时增加视觉吸引力。本教程将深入探讨如何实现图片淡入淡出...

    淡入淡出效果切换图片

    在CSS中,我们可以利用`transition`属性和`opacity`属性来创建淡入淡出效果。首先,将所有图片设置为绝对定位并堆叠在一起,然后通过改变`opacity`属性实现图片的透明度变化。以下是一个简单的例子: ```css img { ...

    商业编程-源码-位图的Alpha淡入淡出显示示例代码.zip

    这个压缩包中的源码提供了一个关于位图Alpha淡入淡出显示的示例,这涉及到透明度控制和图像效果的实现。 Alpha通道是位图中的一个特殊通道,用于表示每个像素的透明度。在24位色彩的位图中,通常有红、绿、蓝三个...

    AudioManager_Unity音频淡入淡出_

    在上述代码中,FadeIn和FadeOut方法接受一个AudioSource实例和淡入/淡出的持续时间。FadeCoroutine协程负责实际的音量变化,使用Mathf.Lerp函数在指定时间内线性插值计算音量。 为了实现AudioManager,我们需要创建...

    图片淡入淡出切换效果实现

    在上述代码中,`switchImage`函数负责切换图片,通过改变`show`和`hidden`类来实现淡入淡出效果。`setInterval`函数则设置了一个定时器,每隔指定时间调用`switchImage`。 这个简单的实现可以作为基础,进一步扩展...

Global site tag (gtag.js) - Google Analytics