• 网络学院
  • IT资讯
  • 操作系统
  • 网络技术
  • 软件应用
  • 办公软件
  • 编程技术
  • 网站架设
  • 数据库类
  • 平面设计
  • 多媒体类
  • 游戏资讯
  • 教学论文
  • 认证考试
用VC实现图象渐显和渐隐
  站点:
  • 首 页
  • 最新软件
  • 文章教程
  • 国内软件
  • 国外软件
  • 绿色软件
  • 源码下载
  • 字体下载
用VC实现图象渐显和渐隐
软件发布 用VC实现图象渐显和渐隐
网络软件 系统工具 应用软件 联络聊天 图形图像 多媒体类 行业软件 游戏娱乐 编程开发 安全相关 教育教学 数码软件 绿软下载
热门软件: QQ 瑞星 pplive e话通 木马克星 千千静听 office2000 五笔字根 Photoshop 视频分割
返回文章教程首页 >> 编程技术 >> VC教程 >> 用VC实现图象渐显和渐隐

用VC实现图象渐显和渐隐

添加时间: 2006-2-13 8:55:18  作者: VC教程  阅读次数:318   来源: http://d9soft.com

        图象的渐显/渐隐被广泛运用与图象处理和多媒提娱乐软件。本文基于windows的调色板动画和时间码技术设计了通用的图象渐显和渐隐算法,并实现了其visual c++程序编码。

  图象的渐显/渐隐是十分重要的图象效果,广泛运用于图象处理和多媒提娱乐软件。渐显/渐隐算法设计的最大困难是速度控制,包括定时和快速改变图象中各象素的颜色。如采用普通的全图扫描算法,则速度较慢,很难真正体现渐显/渐隐效果。  

  利用windows(3.x.95/98/nt)操作系统特殊的调色板管理和时间码定时机制能设计出有效的图象渐显/渐隐算法。windows提供一种被称为调色板动画(palette animation)的颜色处理技术,它通过快速改变颜色调色板中所选取的表项中的颜色能模拟颜色的变化。设置时间码,定时调用该技术使图象颜色渐变就能实现图象的渐显和渐隐。

  一、调色板动画

  在visual c++中实现调色板动画依赖于mfc类库提供的cpalette类和cdc类中的若干成员函数,其基本步骤如下:

  调用cpalette::createpalette(lplogpalette lplogpalette)函数创建逻辑调色板,注意将参数lplogpalette所指向的各颜色表项结构的peflags域设置为pc_reserved,以防止其它窗口同该调色板匹配颜色。;

  调用cdc::selectpalette和cdc::realizepalette函数选择和实现所创建的逻辑调色板;

  调用cpalette::animatepalette函数改变颜色,实现调色板动画;

  动画完成后应恢复系统调色板。

  cpalette::animatepalette是其中最关键的函数,其原型如下:  

  void animatepalette(  

  uint nstartindex, // 起始的表项号  

  uint nnumentries, // 变化的表项数  

  lppaletteentry lppalettecolors ); // 逻辑调色板表项指针  

  lppalettecolors为指向paletteentry结构的指针,其中存储着逻辑调色板将要更新的颜色信息。paletteentry结构定义如下: 

  typedef struct tagpaletteentry { // pe   

  byte pered;   

  byte pegreen;   

  byte peblue;

  byte peflags;  

  } paletteentry;   

  pered、pegreen、peblue分别表示逻辑调色板项的r、g、b颜色分量值。peflags 应被置为pc_reserved 。  

  nstartindex为lppalettecolors中将变化的起始表项号,nnumentries 为lppalettecolors中将变化的表项数。  

  二、时间码定时  

  cwnd::settimer函数可设置一个系统时间码,并指定每经过一定的时间间隔使windows系统发送一个wm_timer消息到窗口的消息队列中。窗口在每当接收到相应的wm_timer消息时做一定的处理,便实现了定时处理。  

  通常应在窗口的消息循环中接受和处理wm_timer消息,这样将很难编制通用的定时操作。通用的定时操作应将定时处理封装在一个函数中,而不与其它的代码纠缠在一起。笔者实现这一技术的技巧是,在循环操作中截获窗口消息,如消息为指定的时间码消息,则进行定时处理;否则分发消息给窗口消息处理机制。如果定时操作已结束,则修改循环标志,退出循环。具体的代码如下: 

  ………………………………

  // 设置时间码,pwnd为处理定时操作的窗口对象指针

  pwnd->settimer(0x100, utimeout, null);  

  // 屏蔽鼠标操作,使定时操作不受影响  

  pwnd->setcapture();  

  // 开始定时操作  

  bool bdone = false;  

  msg msg;

  while (! bdone)  

  {  

  if (::peekmessage(&msg, null, 0, 0, pm_remove))  

  {  

  if (msg.message == wm_timer && msg. wparam == 0x100)  

  {  

  …………………..  

  定时操作代码  

  …………………..  

  // 如定时操作完成,则设置循环标志,结束操作  

  if (定时操作完成)  

  bdone = true;  

  }  

  ::translatemessage(&msg); 

  ::dispatchmessage(&msg);  

  }  

  }  

  // 释放鼠标  

  ::releasecapture();  

  // 删除时间码  

  pwnd->killtimer(0x100);  

  …………………………..  

  函数peekmessage截获窗口消息,translatemessage和dispatchmessage函数解释和分发除指定时间码消息之外的所有消息,以避免丢失消息。  

  三、渐显  

  渐显就是将显示颜色由黑色(rgb(0, 0, 0))逐渐变化为图象各象素的颜色的过程。开始时调用cpalette::getpaletteentries函数保存图象调色板的各逻辑表项信息,然后调用cpalette::setpaletteentries函数将逻辑调色板中各逻辑表项的pered、pegreen、peblue置为0,定时调用cpalette::animatepalette,每次将各逻辑表项的pered、pegreen、peblue值增加一个变化量,直到它们分别等于图象逻辑调色板中各逻辑表项的pered、pegreen、peblue值。

  下面的函数fadein通过对调色板颜色表项中的各颜色分量值先设为0,然后进行递增,直到所有颜色值都恢复成原调色板中颜色值来实现渐显。  

  // 图象渐显效果

  // 参数:  

  // pwnd – 显示图象的窗口  

  // ppal – 调色板指针  

  // ndeta – 各颜色分量的减小量  

  // utimeout – 时间的变化量  

  void fadein(cwnd *pwnd, cpalette *ppal, int ndeta, uint utimeout)   

  {

  // 保留原来的调色板颜色表项  

  int ntotalcolors = ppal->getentrycount();  

  paletteentry palettecolors0[256];

  ppal->getpaletteentries(0, ntotalcolors, palettecolors0);  

  // 先将调色板表项中各颜色分量置为0  

  paletteentry palettecolors1[256];  

  for (int i=0; i
  {  

  palettecolors1[i].pered = 0;  

  palettecolors1[i].pegreen = 0;  

  palettecolors1[i].peblue = 0;  

  palettecolors1[i].peflags = pc_reserved;  

  }

  ppal->setpaletteentries(0, ntotalcolors, palettecolors1);  

  ppal->animatepalette(0, ntotalcolors, palettecolors1);  

  // 设置时间码  

  pwnd->settimer(0x100, utimeout, null);  

  // 开始渐显  

  pwnd->setcapture();  

  bool bdone = false;  

  msg msg;  

  while (! bdone)  

  {  

  if (::peekmessage(&msg, null, 0, 0, pm_remove))  

  {  

  if (msg.message == wm_timer && msg.wparam == 0x100)  

  {  

  cclientdc dc(pwnd);  

  cpalette *poldpal = dc.selectpalette(ppal, false);

  dc.realizepalette();  
  // 递增各颜色分量

  paletteentry palettecolors[256];  

  ppal->getpaletteentries(0, ntotalcolors, palettecolors);  

  bool bredzero=false;  

  bool bgreenzero=false;  

  bool bbluezero=false; 

  for (int i=0; i
  {  

  if (palettecolors[i].pered + ndeta <  

  palettecolors0[i].pered)  

  {  

  palettecolors[i].pered += ndeta;

  bredzero = false;  

  }  

  else if (palettecolors[i].pered + 1 <  

  palettecolors0[i].pered)  

  {  

  palettecolors[i].pered++;  

  bredzero = false;  

  }  

  else  

  bredzero = true;  

  if (palettecolors[i].pegreen + ndeta <  

  palettecolors0[i].pegreen)  

  {  

  palettecolors[i].pegreen += ndeta;  

  bgreenzero = false;

  }

  else if (palettecolors[i].pegreen + 1 <  

  palettecolors0[i].pegreen)  

  {  

  palettecolors[i].pegreen++;  

  bgreenzero = false;  

  }  

  else  

  bgreenzero = true;

  if (palettecolors[i].peblue + ndeta <  

  palettecolors0[i].peblue)  

  {

  palettecolors[i].peblue += ndeta;

  bbluezero = false;

  }  

  else if (palettecolors[i].peblue +1 <  

  palettecolors0[i].peblue)  

  {  

  palettecolors[i].peblue++;  

  bbluezero = false;  

  }  

  else

  bbluezero = true;  

  }

  // 直到恢复原始值结束

  bdone = bredzero && bgreenzero && bbluezero;  

  // 使系统改变调色板

    

    ppal->animatepalette(0, ntotalcolors, palettecolors);  

  }

  ::translatemessage(&msg);

  ::dispatchmessage(&msg);

  }

  }  

  ::releasecapture();  

  pwnd->killtimer(0x100);  

  // 恢复原始调色板  

  ppal->setpaletteentries(0, ntotalcolors, palettecolors0);  

  ppal->animatepalette(0, ntotalcolors, palettecolors0);  

  }  

  四、渐隐

  渐隐就是将显示颜色由图象各象素的颜色逐渐变化为黑色(rgb(0, 0, 0))的过程,即定时调用cpalette::animatepalette,每次将各逻辑表项的pered、pegreen、peblue值减小一个变化量,直到它们都为0。  

  下面的函数fadeout通过对调色板颜色表项中的各颜色分量值进行递减,直到所有颜色值都变成0(即黑色)来实现渐隐。

  // 图象渐隐效果  

  // 参数:

  // pwnd – 显示图象的窗口

    

    // ppal – 调色板指针  

  // ndeta – 各颜色分量的减小量  

  // utimeout – 时间的变化量  

  void fadeout(cwnd *pwnd, cpalette *ppal, int ndeta, uint utimeout)  

  {  

  // 保留原来的调色板颜色表项 

  int ntotalcolors = ppal->getentrycount();  

  paletteentry palettecolors0[256];  

  ppal->getpaletteentries(0, ntotalcolors, palettecolors0);  

  // 设置时间码  

  pwnd->settimer(0x100, utimeout, null);  

  // 开始渐隐  

  pwnd->setcapture(); 

  bool bdone = false;  

  msg msg;  

  while (! bdone)

  {  

  if (::peekmessage(&msg, null, 0, 0, pm_remove))  

  {  

  if (msg.message == wm_timer && msg.wparam == 0x100) 

  {  

  cclientdc dc(pwnd);

  cpalette *poldpal = dc.selectpalette(ppal, false);  

  dc.realizepalette();  

  paletteentry palettecolors[256];

  ppal->getpaletteentries(0, ntotalcolors, palettecolors);  

  bool bredzero=false;  

  bool bgreenzero=false;  

  bool bbluezero=false;  

  // 递减颜色分量  

  for (int i=0; i
  {  

  if (palettecolors[i].pered > ndeta)  

  {  

  palettecolors[i].pered -= ndeta;  

  bredzero = false;

  }  

  else if (palettecolors[i].pered > 1)  

  {  

  palettecolors[i].pered--;  

  bredzero = false;

  }  

  else  

  bredzero = true;  

  if (palettecolors[i].pegreen > ndeta)  

  {  

  palettecolors[i].pegreen -= ndeta;  

  bgreenzero = false;  

  }  

  else if (palettecolors[i].pegreen > 1)  

  {  

  palettecolors[i].pegreen--;  

  bgreenzero = false;  

  }  

  else

  bgreenzero = true;

  if (palettecolors[i].peblue > ndeta)  

  {  

  palettecolors[i].peblue -= ndeta;  

  bbluezero = false;

  }  

  else if (palettecolors[i].peblue > 1)  

  {  

  palettecolors[i].peblue--;  

  bbluezero = false;  

  }

  else

  bbluezero = true;  

  }  

  // 如所有颜色分量都为0,则结束渐隐  

  bdone = bredzero && bgreenzero && bbluezero;  

  // 使系统改变调色板  

  ppal->animatepalette(0, ntotalcolors, palettecolors);  

  }  

  ::translatemessage(&msg);  

  ::dispatchmessage(&msg);

  }  

  }

  ::releasecapture();  

  pwnd->killtimer(0x100);

  // 恢复原始调色板  

  ppal->setpaletteentries(0, ntotalcolors, palettecolors0);  

  ppal->animatepalette(0, ntotalcolors, palettecolors0);  

  }

 

上下文章:

 

上一篇文章: ADO在VC++中进行数据库编程 下一篇文章: VC++ 之Tool Bar控件

相关文章:

  • Word设计师欲重返太空 明春或能实现(图)
  • 应用Privoxy让Chrome实现广告过滤
  • 实现谷歌日历和Thunderbird 同步
  • 无纸化考试流程轻松实现
  • 飞速在线看视频 傲盾加速帮你实现速度感受

相关软件:

  • 修改IIS的BANNER实现操作系统版本的隐藏(PDF)
  • VB.NET面向对象的实现(CHM)

 

快速导航

  • 网络学院
  • 精品汇聚
  • 字体下载
  • 教程下载
  • ASP源码
  • PHP源码
  • Net源码
  • JSP 源码

编程技术分类导航

  • ASP & ASP.NET教程
  • PHP教程
  • JSP教程
  • C/C++教程
  • VB & VB.NET教程
  • VC教程
  • Delphi教程
  • BCB教程
  • VFP教程
  • PB教程
  • JAVA教程
  • XML教程
  • C#教程
  • CGI教程

本类经典文章推荐

  • VC++之Button控件
  • VC++之Static Box控件
  • VC++之Edit Box控件
  • VC++之Static Box控件
  • VC++之Edit Box控件
  • VC++之Scroll Bar
  • VC++之Scroll Bar
  • VC++之List Box/Check List Box控...
  • VC++ Combo Box/Combo Box Ex控件
  • VC++ List Ctrl控件

VC教程阅读排行

  • VC++之List Box/Check List Box控...
  • VC++ List Ctrl控件
  • VC++ Combo Box/Combo Box Ex控件
  • VC++之Button控件
  • VC++之Tab Ctrl控件
  • VC++之Edit Box控件
  • VC++之Edit Box控件
  • VC遍历整个目录树查找文件
  • VC++之Scroll Bar
  • VC使用ActiveX控件常见问题

编程技术阅读总排行

  • VB入门教程之一
  • Java连接数据库实例
  • VC++之List Box/Check List Box控...
  • 第二章 PowerBuilder 入门之创建新...
  • VC++ List Ctrl控件
  • 第一章 什么是PowerBuilder
  • VC++ Combo Box/Combo Box Ex控件
  • 学C++不得不看的一篇文章
  • VB入门教程之二
  • VC++之Button控件

广告位置

字母检索 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 回到顶部

关于我们 | 版权声明 | 免责条款 | 广告联系 | 软件发布 | 下载帮助 | 下载排行 | 网站地图 | 特别鸣谢 | 友情连接

copyright; 2005-2008 D9soft.com 第九软件网 版权所有