当图像信息量较大,采用以上直接显示的方法,可能前面一部分显示后,显示后面一部分时,由于后面一部分还未从文件读出,使显示呈斑驳现象。为了提高显示效果,许多应用程序都采用图像缓冲技术,即先把图像完整装入内存,在缓冲区中绘制图像或图形,然后将缓冲区中绘制好的图像或图形一次性输出在屏幕上。缓冲技术不仅可以解决闪烁问题,并且由于在计算机内存中创建图像,程序可以对图像进行像素级处理,完成复杂的图像变换后再显示。

【例 12-6】小应用程序程序演示图像缓冲显示技术。程序运行时,当鼠标在图像区域内按下时,图像会出现边框,托动鼠标时,图像也随之移动。抬起鼠标后,边框消失。程序将两种状态的图像先放入两个缓冲区,当鼠标拖动时,不断地在新的位置重绘鼠标按下样式的图像鼠标抬起时,重绘鼠标抬起样式的图像。

  1. 鼠标抬起时,重绘鼠标抬起样式的图像。
  2. import java.applet.*;
  3. import java.awt.*;
  4. imprt java.awt.image. * ;
  5. import javax.swing.*;
  6. import java.event.*;
  7. public class Example7_6 extends Applet{
  8. Image myPicture;
  9. /*init()方法中,先定义一个Image对象,并赋予createImage()方法的返回值,接着创建Graphics对象并赋予其图形环境。最后,让Graphics对象调用drawImage()方法显示图像。
  10. 由于这里的Graphics对象offScreenGc是非屏幕对象是,小程序窗口不会有图像显示*/
  11. public void init(){
  12. myPicture = getImage(getCodeBase(), "myPic.JPG");
  13. Image offScreenImage = createImage(size().width, size().height);
  14. Graphics offScreenGc = offScreenImage.getGraphics();
  15. new BufferedDemo(myPicture);
  16. }
  17. /*drawImage()方法的第四个参数是实现ImageObserver接口,在init()方法中,调用drawImage()方法的参数是this,所以小程序要定义imageUpdate()方法*/
  18. public boolean imageUpdate(Image img, int infoFlg, int x, int y, int w, int h){
  19. if (infoFlg = ALLBITS){ // 表示图像已全部装入内存
  20. repaint();
  21. return false;// 防止线程再次调用imageUpdate()方法
  22. }
  23. else
  24. return true;
  25. }
  26. }
  27. /*程序的执行过程是,当小程序调用drawImage()方法时,drawImage()方法将创建一个调用 imageUpdate()方法的线程,在imageUpdate()方法中,测定图像是否已在部分调入内存。创建的线程不断调用imageUpdate()方法,直到该方法返回false为止。参数infoFlg使小程序能知道图像装入内存的情况。当infoFlg等于ALLBITS时,表示图像已全部装入内存。当该方法发现图像已全部装入内存后,置imageLoaded为真,并调用repaint()方法重画小程序窗口。方法返回false防止线程再次调用imageUpdate()方法。*/
  28. class BufferedDemo extends JFrame{
  29. public BufferedDemo(Image img){
  30. this.getContentPane().add(new PicPanel(img));
  31. setTile("双缓技术演示");
  32. setSize(300, 300);
  33. setVisible(true);
  34. }
  35. }
  36. class PicPane extends JPanel implements MouseListener, MouseMotionListener{
  37. int x = 0, y = 0, dx = 0, cy = 0;
  38. BufferedImage bimg1, bimg2;
  39. boolean upstate = true;
  40. public picPanel(Image img){
  41. this.setBackground(Color.white);
  42. this.addMouseListener(this);
  43. this.addMouseMotionListener(this);
  44. bimg1 = new BufferedImage(img.getWidth(this), img.getHeight(this),
  45. BufferedImage.TYPE_INT_ARGB);
  46. bimg2 = new BufferedImage(img.getWidth(this), img.getHeight(this),
  47. BufferedImage.TYPE_INT_ARGB);
  48. Graphics2D g2D1 = bimg1.createGraphics();
  49. Graphics2D g2D2 = bimg2.createGraphics();
  50. g2D1.drawImage(img, 0, 0, this);
  51. g2D2.drawImage(img, 0, 0, this);
  52. g2D2.drawRect(1, 1, img.getWidth(this) - 3, img.getHeight(this) - 3);
  53. }
  54. public void paintComponent(Graphics g){
  55. super.painComponent(g);
  56. Graphics2D g2D = (Graphics2D)g;
  57. if (upState)
  58. g2D.drawImage(bimg1, x, y, this);
  59. else
  60. g2D.drawImage(bimg2.x, y, this);
  61. }
  62. public void mousePress(MouseEvent e){
  63. if (e.getX() >= x && e.getX() < x + bimg1.getWidth(this) && e.getY() >= y&& e.getY() < y + bimg1.getHeight(this)){
  64. upstate = false;
  65. setCursor(Cursor.getPredefinedCursor(Coursor.HAND_CURSOR));
  66. dx = e.getX() - x;
  67. dy = e.getY() - y;
  68. repain();
  69. }
  70. }
  71. public void mouseExited(MouseEvent e){}
  72. public void mouseClicked(MouseEvent e){}
  73. public void mouseEntered(MouseEvent e){}
  74. public void MouseReleased(MouseEvent e){
  75. this.setCursor(Cursor.getpredefinedCursor(Cursor.DEFAULT_CURSOR));
  76. upState = true;
  77. repaint();
  78. }
  79. public void mouseMoved(MouseEvent e){}
  80. public void mouseDragged(MouseEvent e){
  81. if (!upState){
  82. x = e.getX() - dx;
  83. y = e.getY() - dy;
  84. repaint();
  85. }
  86. }
  87. }

程序要创建缓冲区图像,需要引入java.awt.image包中的BufferedImage类。要创建一个缓冲区图,可以调用createImage()方法,该方法返回一个Image对象,然后再将它转换成一个BufferedImage对象。例如,代码:

  1. BufferedImage bimage = (BufferedImage)this.createImage(this.getWidth(),this.getHeight());

也可利用以下构造方法来建立。

  1. BufferedImage(int width,int heigh, int imageType);

其中参数 imageType是图像类型。

使用缓冲区显示图像,需先在缓冲区中准备好图像,再将缓冲区中的图像显示在界面上。显示图像需要图形对象Graphics,可以通过以下方法建立:

  1. Graphics2D g2d = bimge.createGraphics();

系列文章:

Java知多少(101)图像缓冲技术的更多相关文章

  1. Java知多少(完结篇)

    Java知多少(1)语言概述 Java知多少(2)虚拟机(JVM)以及跨平台原理 Java知多少(3) 就业方向 Java知多少(4)J2SE.J2EE.J2ME的区别 Java知多少(5) Java ...

  2. Java知多少(下)

    Java知多少(78)Java向量(Vector)及其应用 Java知多少(79)哈希表及其应用 Java知多少(80)图形界面设计基础 Java知多少(81)框架窗口基础 Java知多少(82)标签 ...

  3. Java知多少(112)数据库之删除记录

    删除数据表也有3种方案 一.使用Statement对象 删除数据表记录的SQL语句的语法是: delete from 表名 where 特定条件 例如 : delete from ksInfo whe ...

  4. Java知多少(111)数据库之修改记录

    修改数据表记录也有3种方案. 一.使用Statement对象 实现修改数据表记录的SQL语句的语法是:    update表名 set 字段名1 = 字段值1,字段名2 = 字段值2,……where特 ...

  5. Java知多少(110)数据库之插入记录

    插入数据表记录有3种方案 一.使用Statement对象 实现插入数据表记录的SQL语句的语法是: insert into 表名(字段名1,字段名2,……)value (字段值1,字段值2,……) 例 ...

  6. Java知多少(109)数据库更新

    数据库更新操作包括数据表创建.删除.以及数据表记录的增加.删除.修改等操作.如果利用数据 SQL命令实现,则利用Statement对旬的executeUpdate()方法,执行SQL的update语句 ...

  7. Java知多少(108)数据库查询简介

    利用Connection对象的createStatement方法建立Statement对象,利用Statement对象的executeQuery()方法执行SQL查询语句进行查询,返回结果集,再形如g ...

  8. Java知多少(107)几个重要的java数据库访问类和接口

    编写访问数据库的Java程序还需要几个重要的类和接口. DriverManager类 DriverManager类处理驱动程序的加载和建立新数据库连接.DriverManager是java.sql包中 ...

  9. Java知多少(106)程序与数据库连接

    一个网络关系数据库应用系统是一个三层次结构.客户机与服务器采用网络连接,客户机端应用程序按通信协议与服务器端的数据库程序通信:数据库服务程序通过SQL命令与数据库管理系统通信. Java程序与数据库连 ...

随机推荐

  1. 潭州课堂25班:Ph201805201 mongo数据 库 第八课 (课堂笔记)

    mongo   进入数据库, exit 退出 show dbs 查数据库 db.createCollection('stu')  创建一个集合, > use binbinswitched to ...

  2. 通俗讲解 异步,非阻塞和 IO 复用

    1. 阅前热身 为了更加形象的说明同步异步.阻塞非阻塞,我们以小明去买奶茶为例. 1.1 同步与异步 同步与异步的理解 同步与异步的重点在消息通知的方式上,也就是调用结果通知的方式. 同步: 当一个同 ...

  3. 使用TVTK库创建一个矩形视图

    from tvtk.api import tvtk # s=tvtk.ConeSource(height=,radius=) # print(s.center) #创建一个长方体数据源,并同时设置长宽 ...

  4. nodejs区分开发环境和生产环境

    参考: https://www.cnblogs.com/suoking/p/5509060.html linux&mac 设置dev,producntion export NODE_ENV=p ...

  5. 工具使用-----Jmeter教程 简单的压力测试

    摘抄于http://www.cnblogs.com/TankXiao/p/4059378.html 以下是英文版的,中文版的也差不多的 Jmeter是一个非常好用的压力测试工具.  Jmeter用来做 ...

  6. scrollview滑动到某区域执行某种方法

    在这里通过  offset.y   检测滑动到的区域 通过if 语句执行需要的方法   -(void)scrollViewDidScroll:(UIScrollView *)scrollView { ...

  7. delphi Tdxribbon 设置背景和skin 皮肤

    https://blog.csdn.net/maxwoods/article/details/8592389 http://www.cnblogs.com/baoluo/archive/2011/04 ...

  8. Activex控件的IObjectSafety接口问题

    我的05年做流氓插件的时候,就注意到了这个问题,只要注册表加入 类似的就可以  HKEY_CLASSES_ROOT\Component    Categories\{7DD95801-9882-11C ...

  9. Unity3D MonoBehaviour的生命周期(lifecycle)

    官方的事件函数的执行顺序中有详解(Link:Execution Order of Event Functions) (图片来源:http://whatiseeinit.blogspot.com/201 ...

  10. Win7下MongoDB的安装和使用

    Win7下MongoDB的安装和使用 1.下载: http://www.mongodb.org/downloads 2.安装: 安装目录为 D:\mongodb\MongoDB 2.6 Standar ...