计算机图形学实验报告6.docx
《计算机图形学实验报告6.docx》由会员分享,可在线阅读,更多相关《计算机图形学实验报告6.docx(30页珍藏版)》请在冰豆网上搜索。
计算机图形学实验报告6
《计算机图形学》实验6实验报告
实验题目:
简单Java绘图板程序
实验内容:
1阅读理解本试验提供的参考资料。
2编写并调通一个简单绘图板的java程序。
参考资料:
1pb.java
2Java图形处理介绍.doc
基本概念:
1在编写显示图形的JAVA程序中,需要经常覆盖一些方法,其中使用的最多的就是paint()、repaint()和update()方法。
Paint():
每次applet被其他窗口覆盖后重新显示时,都会调用paint()方法,在paint()方法中会调用repaint()方法;
Repaint():
repaint()方法强制Applet进行重新绘制。
调用repaint()方法之后会接着调用update()方法。
Repaint()方法有三种调用方式:
●publicvoidrepaint(longtm)
功能:
每隔tm毫秒进行重绘;
●publicvoidrepaint(intx,inty,intwidth,intheight)
功能:
重绘由参数指定的矩形区域;
●publicvoidrepaint(longtm,intx,inty,intwidth,intheight)
功能:
每隔tm毫秒对指定矩形区域进行重绘;
Update():
update()方法默认的行为是先使用背景色填充applet,然后再调用paint()方法
2颜色模型
绘制图形的过程就是布置布置颜色的过程,为了将二进制数字变成屏幕颜色,需要采用一些规则,Java把这个规则包装在颜色模型中。
Java的32位颜色模型
Java将颜色表示为32位。
在缺省情况下,用于表示图形的32位数中8位用于alpha,8位用于红,8位用于绿,8位用于蓝。
这些值恰好放进一个32位的int数中。
ColorModel类(在java.awt.image包中)有两个子类,包装了两大颜色模型:
●DirectColorModel支持将32位整型数分配成用不同位数和位的位置用以表示alpha、红、绿、蓝。
●IndexColorModel支持查找表。
颜色表示成字节,用于对表索引。
真实颜色值是表中的整型数,用缺省颜色模型进行翻译。
直接颜色模型(DirectColorModel)
直接颜色模型在程序中指定整型数中的多少位和哪些位分别用于表示alpaha、红、绿、蓝四个属性。
在这里必须注意的是,在直接颜色模型中,每一个属性的位必须连接,且不能与另一个属性的位重叠。
DirectColorModel类有两个构造器,都要求用一个整数指定模型的位宽(当前模型用32位,旧式颜色模型用8位)。
每种颜色(红、绿、蓝)用一个整数,也可以用第五个整数指定alpha。
●DirectColorModel(intnbits,intredmask,intgreenmask,int,bluemask)
●DirectColorModel(intnbits,intredmask,intgreenmask,intbluemask,intalphamask)
掩膜就是将整数中对应颜色所在位进行设置的整数。
例如,用1位表示红色、3位表示绿色、20位表示蓝色的颜色模型构造如下:
model=newDirectColorModel(32,0x800000,0x700000,0x0fffff);
索引颜色模型(IndexColorModel)
ColorModel类的另一个颜色模型是索引颜色模型IndexColorModel。
索引颜色模型把颜色值看成红、绿、蓝数值查找表中的索引,在Java中索引是个字节。
实际要查找3个表,各对应一个主颜色(另外,你还可以用第4个表查找ALPHA)。
每个表项包含8位,用于指定颜色强度。
对于使用较少颜色的图形,索引颜色模型通过了方便的映射机制,这个机制特别适用于图形要构造成数字信息时。
索引颜色模型也可以用于绘制不规则形状。
IndexColorModel类的构造器有很多过载,最简单的形式是:
IndexColorModel(intnBits,intnColors,bytereds[],bytegreens[],byteblues[])
索引颜色模型的主要好处是包装了查找过程,另一个附带效果是只用8位而不是32位表示图素。
这就节省了75%,这在程序使用几个大图形时效果会很明显。
还有一个好处是加强了图形过滤性能。
3图象的装入
在Java中Image是一个抽象类,是无法构造的。
创建图形时,使用Component类中的CreateImage方法,这种方法通常只是让它的同级件建立图形。
在特定平台上对本地方法的一组调用成为同级件。
使用CreateImage()主要是对本地方法的调用,通过这种调用,返回的对象是Image的特定平台子类。
图形也可以通过Component类的getImage方法从远程文件装入。
远程装载最简单的办法是直接使用getImage连接拥有远程图形文件的机器,装入文件、分析文件、构造并返回图形。
在实际中,Java对远程图形文件都执行下列策略:
所有远程图形都使用异步线程装入。
图形需要使用或“观察”(Observe)时才开始装入线程。
这是因为直接装载会引起很大的延迟。
4imageUpdate的标志值
标志
含义
●ImageObserver.WIDTH
图形宽度已经修改,可以从width参数读或用图形的getwidth()方法读取
●ImageObserver.HEIGHT
图形高度已经修改,可以从height参数读或用图形的getHeight()方法读取
●ImageObserver.PROPERTIES
图形属性已经修改,可以用图形的Getproperties()方法读取
●ImageObserver.SOMEBITS
图形的多个图素已经传送
●ImageObserver.FRAMEBITS
多帧图形的一个帧已经传送
●ImageObserver.ALLBITS
整个图形已经完毕
●ImageObserver.ERROR
生成中出现了错误
●ImageObserver.ABORT
生成异常终止
5内存图象源(MemoryImageSource)
在Java中另一种图形源是内存:
你可以在程序中建立整形或字节数组来表示图素值,并利用Java的MemoryImageSource类构造Image的实例。
MemoryImageSource的构造器调用如下:
MemoryImageSource(intwidth,intheight,int[]pixels,intarrayOffset,intscanwidth)
MemoryImageSource有各种表示颜色的选项。
MemoryImageSource最简单的输入形式是整型数组,正如我们在前面颜色模型中提到的一样,每个整型数用8位(0-7位)表示蓝色,8位(8-15位)表示绿色,8位(16-23位)表示红色,最显著的8位(24-31位)表示颜色的alpha或不透明度。
一般的系统处理无法访问的透明度组合时用绘制无法访问的颜色所用的办法:
配色(dithering),这是因为真正的不透明度需要十分昂贵的硬件设备。
如果MemoryImageSource的整型数组使用的是二维数组,处理出来将会比较容易,但这里的整型数组是一维的。
图素值表示如下:
对于n列图形,前n列表示第一个扫描行;第二n列表示第二个扫描行,等等。
数组排版之后,内存图形源可以从整个数组或部分数组构造。
MemoryImageSource构造器要传入所要图性的尺寸,int数组,数组偏离量和int数组表示的假象图形宽度。
最后一个参数用于所要图形是假想整图的子集时。
6图象生成器、使用者和过滤器(ImageProducer、ImagerConsumer&ImageFileter)
将远程gif文件变成图素值的隐藏对象和相当直观的内存图形源都是图形生成器。
它们实现java.awt.image包中的ImageProducer接口。
图形生成器的任务是将图素值传递给图形使用者。
Java.awt.image包中除了ImageProducer外,还有个ImageConsumer接口。
图形的建立是生成器和使用者之间对话的结果。
生成器/使用者对话是由使用者启动的,使用者告诉生成器开始生成。
生成器作出的响应是报告图形的长度(如果可能),然后开始计算图素值(或开始从远程服务器文件取用)。
生成器随时向使用者发送新图素并告诉使用者任务何时完成。
ImageProcuder和ImageConsumer两个接口比较复杂。
ImageProducer具有允许多个使用者向生成器登记的方法。
ImageConsumer也有允许生成器提供更多关于图形和生成器信息的方法。
ImageFileter
AWT通过允许你在图象生成者和图象使用者之间插入图象过滤器的方式支持对图象的操作。
一个图象过滤器实际上就是一个ImageFilter类,它放置在一个生产者和一个使用者之间,在使用者得到图象之前改变图象的数据。
过滤器子类
第一子类叫CropImageFilter。
构造器接受x、y、width和height。
过滤器取出这些参数指定的图形子集。
第二个子类是RGBImageFilter。
这是个抽象类,其抽象方法FilterRGB(intx、inty、intrgb)应由子类改写。
X和y参数是过滤的图素坐标,rgb是要转换的图素值。
注意rgb表示成缺省颜色模型(alpha:
红、绿、蓝)。
这种方法应返回表示新转变的图素值的int。
通常RGBImageFilter生成子类生成上下文无关的过滤器,即rgb转换算法与转换图素位置和其它图素值无关的过滤器。
算法设计:
1定义点类
classPointimplementsSerializable{
intx,y;
Colorcol;
inttool;
intboarder;
Point(intx,inty,Colorcol,inttool,intboarder){
this.x=x;
this.y=y;
this.col=col;
this.tool=tool;//不同绘图工具
this.boarder=boarder;
}
}
2定义绘图板类paintboard
Paintboard类继承Frame类,用于实现画图板的总体构架。
包括菜单栏设计,工具栏设计,画图区创建,鼠标事件等。
构造方法
paintboard(Strings){
super(s);
addMouseMotionListener(this);
addMouseListener(this);
paintInfo=newVector();//几何图元信息
/*各工具按钮及选择项*/
//颜色选择
ColChoice=newChoice();
ColChoice.add("black");
ColChoice.add("red");
ColChoice.add("blue");
ColChoice.add("green");
ColChoice.addItemListener(this);
//画笔大小选择
SizeChoice=newChoice();
SizeChoice.add("1");
SizeChoice.add("3");
SizeChoice.add("5");
SizeChoice.add("7");
SizeChoice.add("9");
SizeChoice.addItemListener(this);
//橡皮大小选择
EraserChoice=newChoice();
EraserChoice.add("5");
EraserChoice.add("9");
EraserChoice.add("13");
EraserChoice.add("17");
EraserChoice.addItemListener(this);
toolPanel=newPanel();
//命令按钮
clear=newButton("清除");
eraser=newButton("橡皮");
pen=newButton("画笔");
drLine=newButton("画直线");
drCircle=newButton("画圆形");
drRect=newButton("画矩形");
openPic=newButton("打开图画");
savePic=newButton("保存图画");
colchooser=newButton("显示调色板");
//各组件事件监听
clear.addActionListener(this);
eraser.addActionListener(this);
pen.addActionListener(this);
drLine.addActionListener(this);
drCircle.addActionListener(this);
drRect.addActionListener(this);
openPic.addActionListener(this);
savePic.addActionListener(this);
colchooser.addActionListener(this);
//标签
颜色=newLabel("画笔颜色",Label.CENTER);
大小B=newLabel("画笔大小",Label.CENTER);
大小E=newLabel("橡皮大小",Label.CENTER);
//面板添加组件
toolPanel.add(openPic);
toolPanel.add(savePic);
toolPanel.add(pen);
toolPanel.add(drLine);
toolPanel.add(drCircle);
toolPanel.add(drRect);
toolPanel.add(颜色);toolPanel.add(ColChoice);
toolPanel.add(大小B);toolPanel.add(SizeChoice);
toolPanel.add(colchooser);
toolPanel.add(eraser);
toolPanel.add(大小E);toolPanel.add(EraserChoice);
toolPanel.add(clear);
//工具面板到APPLET面板
add(toolPanel,BorderLayout.NORTH);
setBounds(60,60,900,600);setVisible(true);
validate();//强制显示容器
//dialogforsaveandload
openPicture=newFileDialog(this,"打开图画",FileDialog.LOAD);
openPicture.setVisible(false);
savePicture=newFileDialog(this,"保存图画",FileDialog.SAVE);
savePicture.setVisible(false);
//强制关闭窗口响应方法
openPicture.addWindowListener(newWindowAdapter()
{publicvoidwindowClosing(WindowEvente){
openPicture.setVisible(false);}});
savePicture.addWindowListener(newWindowAdapter()
{publicvoidwindowClosing(WindowEvente){
savePicture.setVisible(false);}});
addWindowListener(newWindowAdapter()
{publicvoidwindowClosing(WindowEvente){
System.exit(0);}});
}
绘图方法paint()
publicvoidpaint(Graphicsg){
Graphics2Dg2d=(Graphics2D)g;
Pointp1,p2;
n=paintInfo.size();//几何图元信息
if(toolFlag==2)
g.clearRect(0,0,getSize().width,getSize().height);//清除
for(inti=0;ip1=(Point)paintInfo.elementAt(i);
p2=(Point)paintInfo.elementAt(i+1);
size=newBasicStroke(p1.boarder,BasicStroke.CAP_BUTT,BasicStroke.JOIN_BEVEL);
g2d.setColor(p1.col);
g2d.setStroke(size);
if(p1.tool==p2.tool){
switch(p1.tool){
case0:
//画笔
Line2Dline1=newLine2D.Double(p1.x,p1.y,p2.x,p2.y);
g2d.draw(line1);
break;
case1:
//橡皮
g.clearRect(p1.x,p1.y,p1.boarder,p1.boarder);
break;
case3:
//画直线
Line2Dline2=newLine2D.Double(p1.x,p1.y,p2.x,p2.y);
g2d.draw(line2);
break;
case4:
//画圆
Ellipse2Dellipse=newEllipse2D.Double(p1.x,p1.y,Math.abs(p2.x-p1.x),Math.abs(p2.y-p1.y));
g2d.draw(ellipse);
break;
case5:
//画矩形
Rectangle2Drect=newRectangle2D.Double(p1.x,p1.y,Math.abs(p2.x-p1.x),Math.abs(p2.y-p1.y));
g2d.draw(rect);
break;
case6:
//截断,跳过
i=i+1;
break;
default:
}//endswitch
}//endif
}//endfor
}//end绘图方法paint()
代码:
//定义点类
classPointimplementsSerializable{
intx,y;
Colorcol;
inttool;
intboarder;
Point(intx,inty,Colorcol,inttool,intboarder){
this.x=x;
this.y=y;
this.col=col;
this.tool=tool;//不同绘图工具
this.boarder=boarder;
}
}//点类定义结束
//定义绘图板类paintboard,带事件监听
classpaintboardextendsFrame
implementsActionListener,MouseMotionListener,
MouseListener,ItemListener{
intx=-1,y=-1;
intcon=1;//画笔大小
intEcon=5;//橡皮大小
inttoolFlag=0;//toolFlag:
工具标记
//toolFlag工具对应表:
//(0--画笔);(1--橡皮);(2--清除);
//(3--直线);(4--圆);(5--矩形);
Colorc=newColor(0,0,0);//画笔颜色
BasicStrokesize=newBasicStroke
(con,BasicStroke.CAP_BUTT,BasicStroke.JOIN_BEVEL);//画笔粗细
Pointcutflag=newPoint(-1,-1,c,6,con);//截断标志
VectorpaintInfo=null;//点信息向量组(几何图元信息)
intn=1;
FileInputStreampicIn=null;//文件流保存、读入所画图形
FileOutputStreampicOut=null;
ObjectInputStreamVIn=null;
ObjectOutputStreamVOut=null;
//*工具面板--画笔,直线,圆,矩形,多边形,橡皮,清除*/
PaneltoolPanel;
Buttoneraser,drLine,drCircle,drRect;
Buttonclear,pen;
ChoiceColChoice,SizeChoice,EraserChoice;
Buttoncolchooser;
Label颜色,大小B,大小E;
ButtonopenPic,savePic;
FileDialogopenPicture,savePicture;//文件名会话框
//构造方法
p