外文翻译-译文部分SWT图像.doc_第1页
外文翻译-译文部分SWT图像.doc_第2页
外文翻译-译文部分SWT图像.doc_第3页
外文翻译-译文部分SWT图像.doc_第4页
外文翻译-译文部分SWT图像.doc_第5页
已阅读5页,还剩19页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

沈阳航空航天大学毕业设计(论文)外文翻译译文浅谈SWT 图像 概要SWT的图像类能用来在GUI里显示图象。图像的最普通的来源是从标准文件形式(例如GIF,JPEG,PNG或者BMP)中下载。一些控制,包括按钮和TreeItems,能直接通过setImage方法来展示一幅图像,但是任何控制绘图的事件都允许图像从图表库中提取。SWT的ImageData 类描述制作一幅SWT 图像的原始数据并且决定了屏幕上每个坐标的象素颜色。 这篇文章展示了ImageData类和图像的正确的用法,显示如何从文件中载入图像,和怎样表现透明度,调和,动画,调节比例和光标这样的图表效应。 By Joe Winchester, IBM 2003年9月10日这篇文章的第一部分介绍了颜色并且展示了一幅图像是怎样记录每个象素色值的。 简介 图像生存周期 ImageData 颜色 PaletteData o 索引调色板o 直接调色板 下一部分描述图像为的透明度,调和,动画和如何调节图像比例。 透明度 操作ImageData 保存图像 调和 o 单个 alpha 值 o 每个像素不同的值 图像效应 GIF动画 比例 最后,文章还告诉我们如何应用源映像和面具来在图像中创建光标。 光标 平台光标 惯用 光标 简介 建立一幅SWT 图像的最简单的方法是从公认的图表文件形式中下载它。这包括GIF,BMP(Windows 形式bitmap) ,JPG 和PNG。在最近发布的Eclipse中TIFF形式得到更多的支持。 图像可以从应用建有图像的文件系统中已知的位置载入(Display display, String fileLocation): Image image = new Image(display, C:/eclipse/eclipse/plugins/org.eclipse.platform_2.0.2/eclipse_lg.gif); 不需要费力编码图像的位置,我们通常从规定的相关类中有关的文件夹位置载入图像。这是通过建立输出流时指定文件路径来完成的 Class.getResourceAsStream(String name) ,然后使用结果作为建造者建图像的理由(Display display, InputStream inputStream)。下面的Eclipse 包explorer 展示了com.foo.ShellWithButtonShowingEclipseLogo 和 eclipse_lg.gif在同一个文件夹里。为遵循代码将会从相关类位置下载图像。Image image = new Image(display, ShellWithButtonShowingEclipseLogo.class.getResourceAsStream(eclipse_lg.gif); 一旦图像被创建,它就被用作了控制的一部分,例如按钮和标签,它们能使图表成为其 setImage(Image image) 方法的一部分。 Button button = new Button(shell,SWT.PUSH);button.setImage(image); 我们可以用已建的GC(Drawable drawable)图像库来绘图:GC gc = new GC(image);gc.setForeground(display.getSystemColor(SWT.COLOR_WHITE);gc.drawText(Ive been drawn on,0,0,true);gc.dispose(); 用 GC 来绘制图像会永久改变图像。文章中还有更多的关于如何使用GC的信息。详见 图形库 - 快览拖拽. 图像生存周期载入图像时,第一步是创造独立的ImageData类,用org.eclipse.swt.graphics.ImageData来描述。接下来,数据通过创造一个实际图像实例为一个具体的设备作准备。 当从一个文件直接载入一幅图像时,可以单独建立一个ImageData 对象,然后使用Image(Device device, ImageData imageData)建图像。尽管不是用来被创建图像的相同对象,但是我们可以使用getImageData()方法来取回数据。这是因为当你准备在屏幕上绘制一个图像时比如颜色深度这类属性是不同于最初的图象数据的。 图像的实例是为一个具体的设备作准备的一种基础的资源,当分配资源不再免费时,这些实例就会被处理掉。在SWT中,当一个对象被垃圾站回收时资源是没有最终化的。更多的信息详见SWT: 标准窗口工具: 操作系统管理系统. ImageDataImageData可以被认为是一幅图像的模型,而图像是准备输出一个具体的设备时的映像。 ImageData包括宽度,高度和每个坐标的象素值。图像的初始数据是字节 ,图像的深度指坐标的比特值。1位图像深度可以为每个象素(0和1)储存两个可能值, 4位深度能储存2 4 = 16,8位深度能储存2 8 = 256值,24位深度能为每个像素储存224=1600万不同的值。图像的深度越大像素所需要的字节数越多,而有些文件形式,比如GIF格式,为了通过链接因特网下载图片最初设计只支持最大为8位的图像深度。每个象素值是怎样转化为一种实际颜色的,这取决于类的调色板org.eclipse.swt.graphics.PaletteData.。 下一部分讲解如何用RGB值来表达颜色,和怎样用PaletteData来给每个象素设定特定颜色。 颜色类org.eclipse.swt.graphics.Color是用来管理实现RGB颜色模型的资源。每种颜色由红色,绿色和蓝色三色素(每个都表示没有任何颜色0到全色255之间的一个整数值)组成。Color cyanColor = new Color(display,0,255,255);/ . Code to use the ColorcyanColor.dispose(); SWT中存在一个便节类org.eclipse.swt.graphics.RGB把红色,绿色和蓝色结合于一个单个的对象内。 RGB cyanRGB = new RGB(0,255,255);Color cyanColor = new Color(display,cyanRGB);/ . Code to use the ColorcyanColor.dispose(); 当不再需要颜色实例时,颜色实例会被处理掉。然而RGB并没有必要被处理。这与图像和它的ImageData之间的关系类似,颜色和图像是对象使用自身基础资源的设备,而RGB和ImageData是基础模型数据。 避免创建管理通常使用的颜色实例,显示类可以使用方法Display.getSystemColor(int id). Color cyanColor = display.getSystemColor(SWT.COLOR_CYAN) 来返回。当一个SWT 程序用Display.getSystemColor(int id)来获得颜色时,颜色不能被处理掉。这个经验法则适合任何SWT 资源:“谁创建,谁处理”。 由上面的原则返回cyan颜色实例,因为没有明确地建立过,所以也不应该被随便处理掉。 一种颜色是如何确切呈现在显示器上的,这是由比如显示器深度解决办法等这类因素决定的。 更多关于这个和SWT颜色模型的问题详见SWT 颜色模型。PaletteData有两种PaletteData,一个索引调色板,一个直接调色板。 PaletteData是一个象素值绘制RGB值的模型,因为调色板不代表基础资源,它们也不需要被处理。 索引调色板 索引调色板中每个像素值代表一个数值,然后通过索引调色板来决定实际颜色。可允许索引的的象素值范围大小不超过该图像的深度。 下面的例子是创建一个深度为1位,48*48 的正方形图像和一个索引调色板。索引调色板指定 0 是红色 1是绿色 (根据建造者 RGB 的指令)。ImageDatas 非预置的像素值初始值为 0 (红色), 2个为环 在ImageData的中央设置一个34*34的正方形图像,设定1 (绿色)。PaletteData paletteData = new PaletteData( new RGB new RGB(255,0,0), new RGB(0,255,0); ImageData imageData = new ImageData(48,48,1,paletteData);for(int x=11;x35;x+) for(int y=11;y35;y+) imageData.setPixel(x,y,1); Image image = new Image(display,imageData); 上述例子深度为1位,因此可以储存2种颜色。当图像颜色深度增加时,调色板颜色数量同时增加。索引调色板允许的图像深度为1,2,4,8位,深度为8位时可以提供 28 = 256 种可能的颜色。还需要更高的颜色深度时(例如16,24,或者32) ,就必须使用直接调色板。 直接调色板 不像在索引调色板中,每个像素值对应着调色板索引中的一个颜色,直接调色板允许每个象素值直接记录红,绿和蓝三色素的组成。直接PaletteData 定义了红色,绿色和蓝色面罩。我们把像素值移至左以使面罩的高位与颜色首字节的高位一致,这个过程要求的比特值数就是面罩数量。例如,一24 位直接调色板可分成3部份,低8位用来储存红色,中间的8位储存绿色,而高8 位则储存蓝色。红色的移动面罩是0 xFF,绿色是0 xFF00 而蓝色是0 xFF0000。每个象素值都是24位整数中红色,绿色和蓝色的组合。建立一个索引调色板使用允许红色,绿色,蓝色面罩被详细说明PaletteData palette = new PaletteData(0xFF , 0xFF00 , 0xFF0000); ImageData imageData = new ImageData(48,48,24,palette); 用之前同样的知识, 代码反复说明了放置到两者中任何一个的像素坐标。0xFF (for red) or 0xFF00 (for green). for (int x=0;x48;x+) for(int y=0;y 11 & y 11 & x 操作符来移动颜色组成部分到右侧。如果你正在编写一般代码做这种操作,注意直接调色板中深度24位或32位的颜色用低位存储红色组成部分,而深度16位的颜色相反,红色占高位蓝色占低位。这个原因同Windows内部储存图像,这样创建图像时,几乎没有变换。 imageData中会反复强调两个为环。 第一个是从上到下横穿图像一次,然后 创建一个 int 来容纳每条数据线。用方法 ImageData.getPixels(int x, int y, int getWidth, int pixels, int startIndex) 每次从imageData的字节中选择一条线。这个方法的API有些不规则,因为与其返回数据结果不如声明为空,结果像素数据加入 int 作为方法讨论通过。 像素的int 被反复调用而且每个值都有自己的红色, 绿色和蓝色组成部分被选出。我们希望的是可以判断是否该像素是返白色,如果是就把它转变成纯白色 - 假设所有像素的红绿组成都高于230,这是一个非常好用的规则蓝色组成部分高于150就是返白色int lineData = new intideaImageData.width; for (int y = 0; y ideaImageData.height; y+) ideaImageData.getPixels(0,y,width,lineData,0); / Analyze each pixel value in the line for (int x=0; x 8; int b = (pixelValue & blueShift) 16; if (r 230 & g 230 & b 150) ideaImageData.setPixel(x,y,0xFFFFFF); ; 已经操作构成ImageData的未加工的字节,我们现在已经成功把返白色值改变成纯白色。 保存图像现在既然有了ImageData,其中所有带白色象素都变为白色,并且调色板的透明度象素已经被设置为白色,我们将保存这幅图像,以便下次某个SWT程序需要纯白色的JPF时,可以直接载入文件照原样使用它。将ImageData存到一个文件中使用类org.eclipse.swt.graphics.ImageLoader。图像载入者有一个公开域数据输入到ImageData 。数据域是ImageData的一个阵列,因为这样可以用不止一个框架支持图像文件形式,比如能动的GIFs格式或者交错JPEG 文件。在接下来的 动画 部分会提到更多。ImageLoader imageLoader = new ImageLoader();imageLoader.data = new ImageData ideaImageData;imageLoader.save(C:/temp/Idea_PureWhite.jpg,SWT.IMAGE_JPEG); 完成结果展示如下: 看起来和最初的 Idea.jpg没什么两样,因为我们采用的是白色背景,但是如果我们在油画板上画图,并且设置白色像素透明,就会看到期望的效果 。ImageData pureWhiteIdeaImageData =new ImageData(C:/temp/Idea_PureWhite.jpg);pureWhiteIdeaImageData.transparentPixel = pureWhiteIdeaImageData.palette.getPixel(new RGB(255,255,255); final Image transparentIdeaImage = new Image(display,pureWhiteIdeaImageData); Canvas canvas = new Canvas(shell,SWT.NONE); canvas.addPaintListener(new PaintListener() public void paintControl(PaintEvent e) e.gc.drawImage(transparentIdeaImage,0,0); ); 上述代码中载入Idea_PureWhite.jpg文件后看起来似乎有些奇怪 透明像素设置为白色。为什么不在用ImageLoader创建Idea_PureWhite.jpg文件之前设置透明像素?这是因为JPEG图片格式不支持透明度。GIF 文件支持本机透明度,但是在ImageLoader上把图片改成 SWT.IMAGE_GIF格式不管用,因为GIF格式要用索引调色板,并且仅支持最大8位图片深度,而JPEG格式使用直接调色板且支持最大24位的图片深度。在调用每个像素值和通过找最近颜色创建GIF图片数据之前,两者之间的转化还要分析JPEG创建最适256色调色板所用的颜色。尽管很多商业图形工具都能做到,但是此变换不在本文章范围之内。匹配颜色深度从24位降到8位的像素值涉及到的算法匹配很多像素而不是仅仅一个,这也是为什么当进行不同格式转换时图片质量有时会下降的原因。我们已经展示了Imagedata作为整型值阵列是怎样表达每个像素坐标的还有每个像素值是怎样通过调色板绘制颜色的。这样我们就可以为Idea.jpg调用图象数据,质疑接近于白色的像素,并且把它们转化成纯白色的RGB值。最后我们就能创建 Idea_PureWhite.jpg文件,通过设置这个文件的白色像素透明,Idea_PureWhite.jpg可以用作透明JPG文件。透明度赖于源象素值(图像被绘制)工作 ,一个目的象素值(图像被绘制到) 以及最终确定目的象素值的一个规则。对透明度来说,规则是除非透明像素被用作目的像素时才使用源象素值。另一技术是用指定了申请相关目的资源量得值来创建最终像素值。这样一来就让源图像和现有预绘图背景互相协调这。 调和调和是一项合并两象素值的技术,源像素和目的象素分别指定值来衡量它们受最终目的像素影响多少。255的值是全影响,而0是无影响。SWT 为整个ImageData 提供单个的值,要不然每个象素有它自己的值。 单个值ImageData的整型值是用来指定一个单个的值的,这个单个值是怎样把源象素与目的输入相结合建立目的输出的。下面的列表展示了 Idea_PureWhite.jpg相同的ImageData是怎样用在3幅单独的图像上的。第一原图,然后使用值128,最后值64,注意相同的ImageData在创建每个图像前通过改变值进行连续操作,改变ImageData对已创建的图像无影响。这是因为图像在创建的同时就开始为ImageData的设备显示作准备。 Shell shell = new Shell(display); shell.setLayout(new FillLayout(); ImageData imageData = new ImageData(C:/temp/Idea_PureWhite.jpg);final Image fullImage = new Image(display,imageData); imageData.alpha = 128;final Image halfImage = new Image(display,imageData); imageData.alpha = 64;final Image quarterImage = new Image(display,imageData); Canvas canvas = new Canvas(shell,SWT.NO_REDRAW_RESIZE); canvas.addPaintListener(new PaintListener() public void paintControl(PaintEvent e) e.gc.drawImage(fullImage,0,0); e.gc.drawImage(halfImage,140,0); e.gc.drawImage(quarterImage,280,0); ); 每个象素不同的价值 在允许单个值申请源图像中所有像素的同时,ImageData 允许每个像素有自身的值。这是通过alphaData byte域实现的。这也就允许了获得影响,比如说得到一个图像从顶部到底部的褪色。下面代码创建了 一个alphaData byte, 和两个循环。外循环 y 从 0 到 imageData的高度,内循环 创建一个 byte 表达 imageData 的宽度与初始值,从0表示顶排一直增加到255表示底排。一个系统指针复制 System.arrayCopy 然后为每一排创建 alphaData byte。 ImageData fullImageData = new ImageData(C:/temp/Idea_PureWhite.jpg); int width = fullImageData.width; int height = fullImageData.height;byte alphaData = new byteheight * width;for(int y=0;yheight;y+) byte alphaRow = new bytewidth; for(int x=0;x System.currentTimeMillis() / Wait till the delay time has passed display.asyncExec(new Runnable() public void run() / Increase the variable holding the frame number imageNumber = imageNumber = loader.data.length-1 ? 0 : imageNumber+1; / Draw the new data onto the image ImageData nextFrameData = loader.dataimageNumber; Image frameImage = new Image(display,nextFrameData); gc.drawImage(frameImage,nextFrameData.x,nextFrameData.y); frameImage.dispose(); canvas.redraw(); ); ; shell.open(); thread.start(); 比例在迄今的例子里我们已经从一个文件中载入一幅图像并且在GUI上以原先的尺寸绘制图像, 但是并不总是这样的情况,有时还需要伸展或者缩小这幅图像。有两种方法做到这点。第一,使用GC 伸展和修剪它,使用GC.drawImage,(Image image, int srcX, int srcY, int srcWidth, int srcHeight, int dstX, int dstY, int dstWidth, int dstHeight) ,第2,使用ImageData.scaledTo(int width, int height)建立一个基于比例接收者的新ImageData 对象。 下面代码装载Idea.jpg 图像 ,把大小变成源图像大小的1/2和2倍 使用 ImageData.scaledTo(int width, int height)。 图像还可以使用GC.drawImage(.)重新设置大小,例子展示了两种途径。第一个技术 把细化新的宽度和高度作为绘图事件的一部分。 因为每次重绘画布都要重做比例这样做可能会是低效率的。更好的办法是创建一个最终期望值大小的图像,一次创建一个GC然后绘图在程序中得到一个尺寸不变的图像。结果在下面被显示,并且两种技术生产几乎相同的结果。final Image image = new Image(display, getClass(),getResourceAsStream(Idea.jpg); final int width = image.getBounds().width; final int height = image.getBounds().height; final Image scaled050 = new Image(display, image.getImageData().scaledTo(int)(width*0.5),(int)(height*0.5); final Image scaled200 = new Image(display, image.getImageData().scaledTo(int)(width*2),(int)(height*2); final Image scaledGC200 = new Image(display,(int)(width*2),(int)(height*2); GC gc = new GC(scaledGC200); gc.drawImage(image,0,0,width,height,0,0,width*2,height*2); gc.dispose(); canvas.addPaintListener(new PaintListener() public void paintControl(PaintEvent e) e.gc.drawImage(image,0,0,width,height,0,0,(int)(width*0.5),(int)(height*0.5); e.gc.drawImage(scaled050,100,0); e.gc.drawImage(scaledGC200,0,75); e.gc.drawImage(scaled200,225,175); ); 什么时候使用GC 按比例绘制,和什么时候使用ImageData.scaledTo(.),取决于特别的脚本。GC按比例绘制更迅速因为它是本地的,但是它确实以为你已有GC 和一幅图像。仅仅使用ImageData意味着你不需要非得准备(要求本地资源和处理)的一图像 ,并且ImageData可以被从一个图表文件直接装载(使用建造者ImageData(String fileName) 或者 ImageData(InputStream stream). 通过使用源ImageData 延迟使用本地资源的要点,但是在已设比例的ImageData应用于设备上之前,我们还是需要创建一个新的图像。光标这篇文章的最后的部分介绍了class org.eclipse.swt.graphics。光标负责管理操作系统和鼠标的联系。光标被覆盖在一篇文章的图像上的原因是,你可以从图像上创建任意光标 并且他们说明了图像面罩是怎样工作的。 可以以两种方式建立光标,或者来自一种已定义的的样式或者使用源图像或面罩图像。 平台光标下面展示的SWT 常量就是以确定样式的目录,还有样本图像,但是这些图像会根据操作系统和平台设置的不同而有所变化。CURSOR_APPSTARTINGCURSOR_IBEAMCURSOR_SIZENECURSOR_ARROWCURSOR_NOCURSOR_SIZENESWCURSOR_CROSSCURSOR_SIZEALLCURSOR_SIZENSCURSOR_HANDCURSOR_SIZEECURSOR_SIZENWCURSOR_HELPCURSOR_SIZENCURSOR_SIZESNWSECURSOR_S

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论