中华网校

系列网站: 中华网校 | www.网校.com | 3D模型 | 中华网校教育

电脑网校 | 业界新闻 | 职业网校 | 网校宝典 | 软件下载 | 网校论坛 | 网校联盟

电脑入门 | 网页设计 | 网络编程 | 图形图象 | 三维空间 | 多媒体 | 程序语言 | 操作系统 | 系统专题 | 办公应用 | 软件宝典 | 硬件天下 | 

 

您的位置:首页 >> 程序语言 >> VC/VC.NET >> 新闻正文

用VC实现图象渐显和渐隐  

作者:_  时间:2001-10-12 14:42:59  来自:中华网校  责任编辑:  阅读次数:

摘 要 图象的渐显/渐隐被广泛运用与图象处理和多媒提娱乐软件。本文基于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

   用VC实现图象渐显和渐隐   共有2页  1  2 页

相关文章 最新文章 推荐文章
用VC实现图象渐显和渐隐

  中华网校依法保护知识产权,如果我们的文章有涉及或侵犯您的有关权益,请即时与我们 联系, 注明网址及文章,我们会即时处理或删除,感谢您的合作!中华网校email
  中华网校由广州市中六电脑城智锐计算机专业培训学院及中华网校技术中心提供网络支持未经本站许可任何个人网站、书刊报社一律不得私自复制,转载本站内容!

关于中华网校 | 广告服务 | 版权声明 | 投稿指南 | 网站合作 | 友情链接 | 网站地图

 

版权所有 中华网校 & 智锐网校 1999-2004 COPYRIGHT (C) 1999-2004 www.ZhiRui.com ALL RIGHTS RESERVED

 
/**/