VCeasyx绘图游戏简易教程.docx
《VCeasyx绘图游戏简易教程.docx》由会员分享,可在线阅读,更多相关《VCeasyx绘图游戏简易教程.docx(14页珍藏版)》请在冰豆网上搜索。
VCeasyx绘图游戏简易教程
自己动手建立项目试试,并输入以下代码:
#include<>
voidmain()
{ printf("HelloWorld!
");
}
然后,输入以下代码试试(无需理解代码含义):
{
initgraph(640,480);
line(200,240,440,240);
line(320,120,320,360);
getch();
closegraph();
执行后应该可以看到屏幕正中央有一个十字
2:
简单绘图,学习单步执行
#include<>创建的绘图屏幕640x480,表示横向有640个点,纵向有480个点。
注意:
左上角是原点(0,0),也就是说,y轴和数学的y轴是相反的。
2.getch实现按任意键功能,按任意键后,程序继续执行。
否则,程序会立刻执行closegraph以至于看不到绘制的内容。
[作业]
用线条画出更多的图形,要求不少于10条直线。
[学习单步执行]
完成作业后(务必完成),开始试着单步执行刚才的程序,由于绘图和多线程等因素的限制,请务必按照以下步骤尝试(熟练了以后就不用了):
1.将VC取消最大化,并缩小窗口,能看到代码就行。
2.按一下F10(单步执行),会看到屏幕上出现一个黄色的小箭头,指示将要执行的代码。
3.当箭头指向initgraph语句时,按F10,能看到窗口发生了变化。
4.将新的绘图窗口和VC并排放,相互不要有覆盖。
这步很重要,否则绘图内容将会被VC窗口覆盖。
5.F10执行getch后,记得激活绘图窗口,并按任意键,否则程序不会继续执行。
6.closegraph后,直接按F5执行全部剩余程序,结束。
单步执行很重要,可以让你知道程序执行到哪里是什么效果,哪条语句执行出了问题等等。
3:
熟悉更多的绘图语句
[常用的绘图语句]
line(x1,y1,x2,y2);简单看一下绘图库的帮助文件,了解更多的绘图语句。
2.绘制更丰富的图形内容,不低于20行。
3.将延时语句适当的插入上个作业的代码中,看看执行效果。
注:
绘图语句不需要记住,用的时候翻翻手册就行。
-4:
结合流程控制语句来绘图
[范例]
例如,画10条直线的代码:
for(inty=100;y<200;y+=10)
line(100,y,300,y);
换一下循环的范围和间隔,看看效果。
还可以用来画渐变色,例如:
for(inty=0;y<256;y++)
setcolor(RGB(0,0,y));
[熟悉if语句]
这步需要自学,看看自己手边的书,是怎样讲if语句的,简单看看就行。
配合if语句,实现红色、蓝色交替画线:
if(y/10%2==1) 画围棋棋盘。
2.画中国象棋的棋盘
3.画国际象棋的棋盘,看手册找到颜色填充语句,实现过期象棋棋盘的区块填充。
4.自学while语句。
学到这里,已经可以画出很多东西了。
把自己想象中的图案绘制一下吧。
5:
数学知识在绘图中的运用
1.最简单的,来个全屏的渐变色吧,是上一课的扩展。
就是需要将0~255的颜色和0~479的y轴对应起来
c表示颜色,范围0~255
y表示y轴,范围0~479
于是:
c/255=y/479
c=y/479*255=y*255/479(先算乘法再算除法可以提高精度)
看代码:
intc;
for(inty=0;y<480;y++)
c=y*255/479;
setcolor(RGB(0,0,c));
line(0,y,639,y);
试试效果吧。
2.画一个圆形的渐变色
首先,我们要用到圆形的基本公式:
x*x+y*y=r*r
让弧度从0~2*,然后需要根据弧度和半径算出(x,y),
用pi表示圆周率
用r表示半径
用a表示弧度(小数)
用c表示颜色
x=r*cos(a)
y=r*sin(a)
c=a*255/(2*pi)
看看代码:
doublea;
intx,y,r=200;
for(a=0;a { x=(int)(r*cos(a)+320+; y=(int)(r*sin(a)+240+; c=(int)(a*255/(2*PI)+; setcolor(RGB(c,0,0)); line(320,240,x,y); } getch(); closegraph();} 6:实现简单动画所谓动画,其实是连续显示一系列图形而已。结合到程序上,我们需要以下几个步骤:1.绘制图像2.延时3.擦掉图像循环以上即可实现动画。举一个例子,我们实现一条直线从上往下移动:#include<>#include<>voidmain(){ initgraph(640,480); for(inty=0;y<480;y++) { 。每隔100毫秒输出一次。按ESC退出。注:ESC的ASCII码是27。完整代码如下:#include<>#include<>#include<>voidmain(){ charc=0; while(c!=27) { if(kbhit()) c=getch(); else c='.'; printf("%c",c); Sleep(100); }}结合上一课的简单动画,就可以做出来靠按键移动的图形了吧,看以下代码,实现as控制圆的左右移动:#include<>#include<>voidmain(){ initgraph(640,480); intx=320; 上下的控制;2.边界检测;3.结合kbhit实现惯性移动(即按一下方向键,圆就会一直向这个方向移动)注:上下左右等按键的控制,会返回2个字符。由于该系列教程面向初学者,因此有兴趣的请查看MSDN。8:用函数简化相同图案的制作实际中有许多类似的图案,如果一一单独绘制,太麻烦。于是,我们需要一个公用的绘制过程,就是函数。例如,我们需要画5个三角形,位于不同的位置。我们可以将绘制单个三角形的过程写成函数,函数内是一个独立的程序段,这个绘制过程很简单。然后,在需要绘制的时候,调用这个函数即可。可以通过参数来解决细微差异(图案的坐标、颜色等),例如:#include<>#include<>绘制Windows自带游戏“扫雷”的初始界面。 9:绘图中的位运算位运算和绘图有什么关系?先举个例子来个感性认识:使用XOR运算可以实现擦除图形后不破坏背景,这在时钟程序中绘制表针是很有用的。稍后我们会给出这样的例子。一、位运算的运算法则位运算主要分4种:NOT、AND、OR、XOR位运算的运算对象是二进制数(十进制要转换为二进制,计算机会自动转换)。运算法则如下:1.NOT表示“取反”,将二进制位的1变0、0变1。C语言用符号~表示。如:二进制:~1101=0010用十进制表示就是:~13=22.AND表示“并且”,只有两数的对应二进制位都为1,结果的二进制位才为1;否则,结果的二进制位为0。C语言用符号&表示。如:二进制:1101&0110=0100用十进制表示就是:13&6=43.OR表示“或者”,两数的对应二进制位只要有一个是1,结果的二进制位就是1;否则,结果的二进制位为0。C语言用符号|表示。如:二进制:0101|0110=0111用十进制表示就是:5|6=74.XOR表示“异或”,两数的对应二进制位不同,结果的二进制位为1;相同,结果的二进制位为0。C语言用符号^表示。如:二进制:0101^1110=1011以上只是简单介绍一下,详细的还是请大家看课本上的讲解。二、位运算的应用位运算的应用很多,例如AND和OR在获取和设置标志位时经常使用。更多的,以后大家会逐渐遇到,暂时先记下有这么回事。这里着重说一下XOR运算,它有一个重要的特性:(a^b)^b=a也就是说,a^b之后可能是某些其它数字,但是只要再^b一下,就又成了a。一些简单的加密就用的XOR的这个特性。至于绘图,假如a是背景图案,b是将要绘制的图案,只要用XOR方式绘图,连续绘两次,那么背景是不变的。三、演示我们来一个简单的绘图XOR运算演示:#include<>#include<>voidmain(){ initgraph(640,480); .下面举一个综合的例子(我偷点懒,直接粘贴的绘图库帮助里面的鼠标范例),该程序会用红色的点标出鼠标移动的轨迹,按左键画一个小方块,按Ctrl+左键画一个大方块,按右键退出:#include<>#include<>#include<>voidmain(){ 画一个填充的三角形,要用鼠标点选三角形的三个顶点。提示:可以用fillpoly函数画多边形。2.写一个“涂格子(也叫点灯)”的游戏。详细规则可以试玩网上的各种版本。3.如果有精力,尝试写一个扫雷吧(这个有点难度,能实现多少就实现多少,无法实现的功能先放下)。11:随机函数[随机函数简介]游戏中,许多情况都是随即发生的。还有一些图案程序,例如屏保,也是随即运动的。这就需要用随机函数。随机函数很简单,只有一个:rand()该函数返回0~32767之间的一个整数。(不需要记住32767这个数字,大概知道这个范围就行了)该函数在头文件<>中,使用前记得引用。[简单测试]来写个程序测试一下:#include<>#include<>voidmain(){ intr; for(inti=0;i<10;i++) { r=rand(); printf("%d\n",r); }}执行后,可以看到输出了10个随机数字。[指定范围的随机函数]实际中,我们经常要产生指定范围的随机函数,通常我们用求余数的办法。例如,产生0~9之间的随机数,只需要将任意产生的随机数除以10求余数即可。求余数的运算符号是%,我们可以这样做: r=rand()%10;修改前面的测试程序执行后可以看到,产生的数字都是小于10的。如果是1~6之间的怎样求呢? r=rand()%6+1;无论产生什么样范围的随机函数,都是通过各种运算将随机数的范围[0,32767]修改为自己需要的范围。[随机种子]做了多次试验,我们会发现一个问题:虽然产生的数字是随机的,但每次产生的数字序列都一样。为了解决这个问题,我们需要用“随机种子”。随机函数的产生原理简单来说,就是:前一个随机函数的值,决定下一个随机函数的值。根据这个原理我们可以知道:只要第一个随机函数的值确定了,那么后面数字序列就是确定的。如果我们想的得到不同的数字序列,我们需要确定第一个随机函数的值,对于设置第一个随机函数的值,叫做设置“随机种子”。易知,随机种子设置一次即可。设置随机种子的函数如下:srand(种子);通常,我们用当前时间来做随机种子:srand((unsigned)time(NULL));因为使用time函数,所以记得引用<>。[绘图中的应用]来一个简单的程序,在屏幕上任意位置画任意颜色的点(按任意键退出):#include<>#include<>#include<>#include<>voidmain(){ srand((unsigned)time(NULL)); initgraph(640,480); intx,y,c; while(!kbhit()) { x=rand()%640; y=rand()%480; c=RGB(rand()%256,rand()%256,rand()%256); putpixel(x,y,c); } closegraph();}[作业]1.回顾一下第6课“实现简单动画”的作业:绘制一个沿45度移动的球,碰到窗口边界后反弹。将这个球改为任意方向运动,碰到边界后任意反弹。12:数组[一维数组]数组可以实现批量操作。比如,我们产生10个随机数,产生后先保存起来,然后输出最大的: intn[10]; inti; for(i=0;i<10;i++) n[i]=rand()%1000; 回顾一下上一节课的作业,绘制一个任意反弹的球。这次,将程序修改成屏幕上有10个任意反弹的球。2.如果反弹的不是球,而是点呢?再将某些点之间用线连起来,就可以做一个屏保“变幻线”的程序了。试试做一个。3.看完前面的12节课,像贪吃蛇、俄罗斯方块这样的程序都可以做了吧,有时间就尝试写一下。如果遇到问题,贴吧里贴出来,大家一起讨论。13:getimage/putimage/IMAGE 的用法getimage/putimage这一组命令和IMAGE对象可以实现加载图片或保存指定区域等功能,下面逐个介绍。(有点类似tc中的imagesize)[加载图片]实现加载图片主要分三步:1.定义IMAGE对象2.读取图片至IMAGE对象3.显示IMAGE对象很简单,我们看一下完整的代码:#include<>#include<>voidmain(){ initgraph(640,480); IMAGEimg; 用线条、圆等各种基础绘图语句画一个“汽车”,然后用getimage/putimage实现该“汽车”的平滑移动。2.自己学一下帮助中BeginBatchDraw/FlushBatchDraw/EndBatchDraw三个函数,可以进一步优化“平滑移动”的效果。这三个命令挺简单的,一看就懂。14:通过位运算实现颜色的分离与处理[颜色基础]在EasyX库中,颜色是一个int类型的数据,转换为16进制后的颜色格式是0xbbggrr,其中,bb/gg/rr分别表示两位十六进制的蓝/绿/红颜色值,每种颜色的范围是0x0~0xff,转换为十进制就是0~255。举几个颜色标示的例子:颜色 直接表示 RGB宏标示纯绿色 0x00ff00 RGB(0,255,0)青色 0xffff00 RGB(255,255,0) 注:青=蓝+绿中灰色 0x7f7f7f RGB(127,127,127)黄色 0x00ffff RGB(0,255,255) 注:黄=红+绿例如设置绘图颜色为黄色,可以多种方法,例如:setcolor(YELLOW);setcolor(RGB(0,255,255));setcolor(0x00ffff);[获取颜色]getpixel是用来获取屏幕颜色的函数,其返回值为int类型的颜色。例如:intc=getpixel(100,100);该语句将返回坐标(100,100)位置的颜色。[颜色分离与处理]有时候我们需要修改颜色某一位的值,这时,可以通过位运算来实现。比如,我们想把某一个点的颜色的红色部分去掉,可以这么做:intc=getpixel(100,100);c&=0xffff00;putpixel(100,100);我们来看一个完整的程序,这个程序,将图片左半部中的红色“去掉”了,就像是显示器“缺色”的效果:#include<>#include<>voidmain(){ initgraph(640,480); 实现提高/降低图像亮度的程序。2.自己搜索“灰度算法”,实现彩色图像转换为灰度图像。(0)回复1楼2010-06-2714:37举报 |BestAns吧主9关于效率问题,暂时不在讨论范围之内。有兴趣的可以看看这篇关于灰度算法效率的文章:转自:彩色转灰度算法彻底学习 搜索:图形学 file:Name:彩色转灰度算法彻底学习Author:zyl910Version:Updata:2006-5-22 最近突然又对图形学有了兴趣,翻出了多年前学习图形学的笔记,感触良多。于是将它们整理好发了上来。一、基础 对于彩色转灰度,有一个很著名的心理学公式:Gray=R*+G*+B*二、整数算法 而实际应用时,希望避免低速的浮点运算,所以需要整数算法。 注意到系数都是3位精度的没有,我们可以将它们缩放1000倍来实现整数运算算法:Gray=(R*299+G*587+B*114+500)/1000 RGB一般是8位精度,现在缩放1000倍,所以上面的运算是32位整型的运算。注意后面那个除法是整数除法,所以需要加上500来实现四舍五入。 就是由于该算法需要32位运算,所以该公式的另一个变种很流行:Gray=(R*30+G*59+B*11+50)/100 但是,虽说上一个公式是32位整数运算,但是根据80x86体系的整数乘除指令的特点,是可以用16位整数乘除指令来运算的。而且现在32位早普及了(AMD64都出来了),所以推荐使用上一个公式。三、整数移位算法 上面的整数算法已经很快了,但是有一点仍制约速度,就是最后的那个除法。移位比除法快多了,所以可以将系数缩放成2的整数幂。 习惯上使用16位精度,2的16次幂是65536,所以这样计算系数:*65536=≈19595*65536+=+=≈38469*65536+=+=7472 可能很多人看见了,我所使用的舍入方式不是四舍五入。四舍五入会有较大的误差,应该将以前的计算结果的误差一起计算进去,舍入方式是去尾法: 写成表达式是:Gray=(R*19595+G*38469+B*7472)>>16 2至20位精度的系数:Gray=(R*1+G*2+B*1)>>2Gray=(R*2+G*5+B*1)>>3Gray=(R*4+G*10+B*2)>>4Gray=(R*9+G*19+B*4)>>5Gray=(R*19+G*37+B*8)>>6Gray=(R*38+G*75+B*15)>>7Gray=(R*76+G*150+B*30)>>8Gray=(R*153+G*300+B*59)>>9Gray=(R*306+G*601+B*117)>>10Gray=(R*612+G*1202+B*234)>>11Gray=(R*1224+G*2405+B*467)>>12Gray=(R*2449+G*4809+B*934)>>13Gray=(R*4898+G*9618+B*1868)>>14Gray=(R*9797+G*19235+B*3736)>>15Gray=(R*19595+G*38469+B*7472)>>16Gray=(R*39190+G*76939+B*14943)>>
x=(int)(r*cos(a)+320+;
y=(int)(r*sin(a)+240+;
c=(int)(a*255/(2*PI)+;
setcolor(RGB(c,0,0));
line(320,240,x,y);
6:
实现简单动画
所谓动画,其实是连续显示一系列图形而已。
结合到程序上,我们需要以下几个步骤:
1.绘制图像
2.延时
3.擦掉图像
循环以上即可实现动画。
举一个例子,我们实现一条直线从上往下移动:
。
每隔100毫秒输出一次。
按ESC退出。
ESC的ASCII码是27。
完整代码如下:
charc=0;
while(c!
=27)
if(kbhit())
c=getch();
else
c='.';
printf("%c",c);
Sleep(100);
结合上一课的简单动画,就可以做出来靠按键移动的图形了吧,看以下代码,实现as控制圆的左右移动:
intx=320;
上下的控制;
2.边界检测;
3.结合kbhit实现惯性移动(即按一下方向键,圆就会一直向这个方向移动)
上下左右等按键的控制,会返回2个字符。
由于该系列教程面向初学者,因此有兴趣的请查看MSDN。
8:
用函数简化相同图案的制作
实际中有许多类似的图案,如果一一单独绘制,太麻烦。
于是,我们需要一个公用的绘制过程,就是函数。
例如,我们需要画5个三角形,位于不同的位置。
我们可以将绘制单个三角形的过程写成函数,函数内是一个独立的程序段,这个绘制过程很简单。
然后,在需要绘制的时候,调用这个函数即可。
可以通过参数来解决细微差异(图案的坐标、颜色等),例如:
绘制Windows自带游戏“扫雷”的初始界面。
9:
绘图中的位运算
位运算和绘图有什么关系?
先举个例子来个感性认识:
使用XOR运算可以实现擦除图形后不破坏背景,这在时钟程序中绘制表针是很有用的。
稍后我们会给出这样的例子。
一、位运算的运算法则
位运算主要分4种:
NOT、AND、OR、XOR
位运算的运算对象是二进制数(十进制要转换为二进制,计算机会自动转换)。
运算法则如下:
1.NOT
表示“取反”,将二进制位的1变0、0变1。
C语言用符号~表示。
如:
二进制:
~1101=0010
用十进制表示就是:
~13=2
2.AND
表示“并且”,只有两数的对应二进制位都为1,结果的二进制位才为1;否则,结果的二进制位为0。
C语言用符号&表示。
1101&0110=0100
13&6=4
3.OR
表示“或者”,两数的对应二进制位只要有一个是1,结果的二进制位就是1;否则,结果的二进制位为0。
C语言用符号|表示。
0101|0110=0111
5|6=7
4.XOR
表示“异或”,两数的对应二进制位不同,结果的二进制位为1;相同,结果的二进制位为0。
C语言用符号^表示。
0101^1110=1011
以上只是简单介绍一下,详细的还是请大家看课本上的讲解。
二、位运算的应用
位运算的应用很多,例如AND和OR在获取和设置标志位时经常使用。
更多的,以后大家会逐渐遇到,暂时先记下有这么回事。
这里着重说一下XOR运算,它有一个重要的特性:
(a^b)^b=a
也就是说,a^b之后可能是某些其它数字,但是只要再^b一下,就又成了a。
一些简单的加密就用的XOR的这个特性。
至于绘图,假如a是背景图案,b是将要绘制的图案,只要用XOR方式绘图,连续绘两次,那么背景是不变的。
三、演示
我们来一个简单的绘图XOR运算演示:
initgraph(640,480); .
下面举一个综合的例子(我偷点懒,直接粘贴的绘图库帮助里面的鼠标范例),该程序会用红色的点标出鼠标移动的轨迹,按左键画一个小方块,按Ctrl+左键画一个大方块,按右键退出:
画一个填充的三角形,要用鼠标点选三角形的三个顶点。
提示:
可以用fillpoly函数画多边形。
2.写一个“涂格子(也叫点灯)”的游戏。
详细规则可以试玩网上的各种版本。
3.如果有精力,尝试写一个扫雷吧(这个有点难度,能实现多少就实现多少,无法实现的功能先放下)。
11:
随机函数
[随机函数简介]
游戏中,许多情况都是随即发生的。
还有一些图案程序,例如屏保,也是随即运动的。
这就需要用随机函数。
随机函数很简单,只有一个:
rand()
该函数返回0~32767之间的一个整数。
(不需要记住32767这个数字,大概知道这个范围就行了)
该函数在头文件<>中,使用前记得引用。
[简单测试]
来写个程序测试一下:
intr;
for(inti=0;i<10;i++)
r=rand();
printf("%d\n",r);
执行后,可以看到输出了10个随机数字。
[指定范围的随机函数]
实际中,我们经常要产生指定范围的随机函数,通常我们用求余数的办法。
例如,产生0~9之间的随机数,只需要将任意产生的随机数除以10求余数即可。
求余数的运算符号是%,我们可以这样做:
r=rand()%10;
修改前面的测试程序执行后可以看到,产生的数字都是小于10的。
如果是1~6之间的怎样求呢?
r=rand()%6+1;
无论产生什么样范围的随机函数,都是通过各种运算将随机数的范围[0,32767]修改为自己需要的范围。
[随机种子]
做了多次试验,我们会发现一个问题:
虽然产生的数字是随机的,但每次产生的数字序列都一样。
为了解决这个问题,我们需要用“随机种子”。
随机函数的产生原理简单来说,就是:
前一个随机函数的值,决定下一个随机函数的值。
根据这个原理我们可以知道:
只要第一个随机函数的值确定了,那么后面数字序列就是确定的。
如果我们想的得到不同的数字序列,我们需要确定第一个随机函数的值,对于设置第一个随机函数的值,叫做设置“随机种子”。
易知,随机种子设置一次即可。
设置随机种子的函数如下:
srand(种子);
通常,我们用当前时间来做随机种子:
srand((unsigned)time(NULL));
因为使用time函数,所以记得引用<>。
[绘图中的应用]
来一个简单的程序,在屏幕上任意位置画任意颜色的点(按任意键退出):
intx,y,c;
while(!
kbhit())
x=rand()%640;
y=rand()%480;
c=RGB(rand()%256,rand()%256,rand()%256);
putpixel(x,y,c);
1.回顾一下第6课“实现简单动画”的作业:
绘制一个沿45度移动的球,碰到窗口边界后反弹。
将这个球改为任意方向运动,碰到边界后任意反弹。
12:
数组
[一维数组]
数组可以实现批量操作。
比如,我们产生10个随机数,产生后先保存起来,然后输出最大的:
intn[10];
inti;
for(i=0;i<10;i++)
n[i]=rand()%1000;
回顾一下上一节课的作业,绘制一个任意反弹的球。
这次,将程序修改成屏幕上有10个任意反弹的球。
2.如果反弹的不是球,而是点呢?
再将某些点之间用线连起来,就可以做一个屏保“变幻线”的程序了。
试试做一个。
3.看完前面的12节课,像贪吃蛇、俄罗斯方块这样的程序都可以做了吧,有时间就尝试写一下。
如果遇到问题,贴吧里贴出来,大家一起讨论。
13:
getimage/putimage/IMAGE 的用法
getimage/putimage这一组命令和IMAGE对象可以实现加载图片或保存指定区域等功能,下面逐个介绍。
(有点类似tc中的imagesize)
[加载图片]
实现加载图片主要分三步:
1.定义IMAGE对象
2.读取图片至IMAGE对象
3.显示IMAGE对象
很简单,我们看一下完整的代码:
IMAGEimg; 用线条、圆等各种基础绘图语句画一个“汽车”,然后用getimage/putimage实现该“汽车”的平滑移动。
2.自己学一下帮助中BeginBatchDraw/FlushBatchDraw/EndBatchDraw三个函数,可以进一步优化“平滑移动”的效果。
这三个命令挺简单的,一看就懂。
14:
通过位运算实现颜色的分离与处理
[颜色基础]
在EasyX库中,颜色是一个int类型的数据,转换为16进制后的颜色格式是0xbbggrr,其中,bb/gg/rr分别表示两位十六进制的蓝/绿/红颜色值,每种颜色的范围是0x0~0xff,转换为十进制就是0~255。
举几个颜色标示的例子:
颜色 直接表示 RGB宏标示
纯绿色 0x00ff00 RGB(0,255,0)
青色 0xffff00 RGB(255,255,0) 注:
青=蓝+绿
中灰色 0x7f7f7f RGB(127,127,127)
黄色 0x00ffff RGB(0,255,255) 注:
黄=红+绿
例如设置绘图颜色为黄色,可以多种方法,例如:
setcolor(YELLOW);
setcolor(RGB(0,255,255));
setcolor(0x00ffff);
[获取颜色]
getpixel是用来获取屏幕颜色的函数,其返回值为int类型的颜色。
例如:
intc=getpixel(100,100);
该语句将返回坐标(100,100)位置的颜色。
[颜色分离与处理]
有时候我们需要修改颜色某一位的值,这时,可以通过位运算来实现。
比如,我们想把某一个点的颜色的红色部分去掉,可以这么做:
c&=0xffff00;
putpixel(100,100);
我们来看一个完整的程序,这个程序,将图片左半部中的红色“去掉”了,就像是显示器“缺色”的效果:
实现提高/降低图像亮度的程序。
2.自己搜索“灰度算法”,实现彩色图像转换为灰度图像。
(0)
回复
1楼
2010-06-2714:
37
举报 |
BestAns
吧主
9
关于效率问题,暂时不在讨论范围之内。
有兴趣的可以看看这篇关于灰度算法效率的文章:
转自:
彩色转灰度算法彻底学习
搜索:
图形学
file:
Name:
Author:
zyl910
Version:
Updata:
2006-5-22
最近突然又对图形学有了兴趣,翻出了多年前学习图形学的笔记,感触良多。
于是将它们整理好发了上来。
一、基础
对于彩色转灰度,有一个很著名的心理学公式:
Gray=R*+G*+B*
二、整数算法
而实际应用时,希望避免低速的浮点运算,所以需要整数算法。
注意到系数都是3位精度的没有,我们可以将它们缩放1000倍来实现整数运算算法:
Gray=(R*299+G*587+B*114+500)/1000
RGB一般是8位精度,现在缩放1000倍,所以上面的运算是32位整型的运算。
注意后面那个除法是整数除法,所以需要加上500来实现四舍五入。
就是由于该算法需要32位运算,所以该公式的另一个变种很流行:
Gray=(R*30+G*59+B*11+50)/100
但是,虽说上一个公式是32位整数运算,但是根据80x86体系的整数乘除指令的特点,是可以用16位整数乘除指令来运算的。
而且现在32位早普及了(AMD64都出来了),所以推荐使用上一个公式。
三、整数移位算法
上面的整数算法已经很快了,但是有一点仍制约速度,就是最后的那个除法。
移位比除法快多了,所以可以将系数缩放成2的整数幂。
习惯上使用16位精度,2的16次幂是65536,所以这样计算系数:
*65536=≈19595
*65536+=+=≈38469
*65536+=+=7472
可能很多人看见了,我所使用的舍入方式不是四舍五入。
四舍五入会有较大的误差,应该将以前的计算结果的误差一起计算进去,舍入方式是去尾法:
写成表达式是:
Gray=(R*19595+G*38469+B*7472)>>16
2至20位精度的系数:
Gray=(R*1+G*2+B*1)>>2
Gray=(R*2+G*5+B*1)>>3
Gray=(R*4+G*10+B*2)>>4
Gray=(R*9+G*19+B*4)>>5
Gray=(R*19+G*37+B*8)>>6
Gray=(R*38+G*75+B*15)>>7
Gray=(R*76+G*150+B*30)>>8
Gray=(R*153+G*300+B*59)>>9
Gray=(R*306+G*601+B*117)>>10
Gray=(R*612+G*1202+B*234)>>11
Gray=(R*1224+G*2405+B*467)>>12
Gray=(R*2449+G*4809+B*934)>>13
Gray=(R*4898+G*9618+B*1868)>>14
Gray=(R*9797+G*19235+B*3736)>>15
Gray=(R*39190+G*76939+B*14943)>>
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1