举例解析Java的图像缓冲技术的使用
作者:goldensun 发布时间:2022-09-08 17:17:17
标签:Java,图像缓冲
当图像信息量较大,采用以上直接显示的方法,可能前面一部分显示后,显示后面一部分时,由于后面一部分还未从文件读出,使显示呈斑驳现象。为了提高显示效果,许多应用程序都采用图像缓冲技术,即先把图像完整装入内存,在缓冲区中绘制图像或图形,然后将缓冲区中绘制好的图像或图形一次性输出在屏幕上。缓冲技术不仅可以解决闪烁问题,并且由于在计算机内存中创建图像,程序可以对图像进行像素级处理,完成复杂的图像变换后再显示。
【例】小应用程序程序演示图像缓冲显示技术。程序运行时,当鼠标在图像区域内按下时,图像会出现边框,托动鼠标时,图像也随之移动。抬起鼠标后,边框消失。程序将两种状态的图像先放入两个缓冲区,当鼠标拖动时,不断地在新的位置重绘鼠标按下样式的图像鼠标抬起时,重绘鼠标抬起样式的图像。
import java.applet.*;
import java.awt.*;
imprt java.awt.image. * ;
import javax.swing.*;
import java.event.*;
public class Example7_6 extends Applet{
Image myPicture;
/*init()方法中,先定义一个Image对象,并赋予createImage()方法的返回值,接着创建Graphics对象并赋予其图形环境。最后,让Graphics对象调用drawImage()方法显示图像。
由于这里的Graphics对象offScreenGc是非屏幕对象是,小程序窗口不会有图像显示*/
public void init(){
myPicture = getImage(getCodeBase(), "myPic.JPG");
Image offScreenImage = createImage(size().width, size().height);
Graphics offScreenGc = offScreenImage.getGraphics();
new BufferedDemo(myPicture);
}
/*drawImage()方法的第四个参数是实现ImageObserver接口,在init()方法中,调用drawImage()方法的参数是this,所以小程序要定义imageUpdate()方法*/
public boolean imageUpdate(Image img, int infoFlg, int x, int y, int w, int h){
if (infoFlg = ALLBITS){ // 表示图像已全部装入内存
repaint();
return false;// 防止线程再次调用imageUpdate()方法
}
else
return true;
}
}
/*程序的执行过程是,当小程序调用drawImage()方法时,drawImage()方法将创建一个调用 imageUpdate()方法的线程,在imageUpdate()方法中,测定图像是否已在部分调入内存。创建的线程不断调用imageUpdate()方法,直到该方法返回false为止。参数infoFlg使小程序能知道图像装入内存的情况。当infoFlg等于ALLBITS时,表示图像已全部装入内存。当该方法发现图像已全部装入内存后,置imageLoaded为真,并调用repaint()方法重画小程序窗口。方法返回false防止线程再次调用imageUpdate()方法。*/
class BufferedDemo extends JFrame{
public BufferedDemo(Image img){
this.getContentPane().add(new PicPanel(img));
setTile("双缓技术演示");
setSize(300, 300);
setVisible(true);
}
}
class PicPane extends JPanel implements MouseListener, MouseMotionListener{
int x = 0, y = 0, dx = 0, cy = 0;
BufferedImage bimg1, bimg2;
boolean upstate = true;
public picPanel(Image img){
this.setBackground(Color.white);
this.addMouseListener(this);
this.addMouseMotionListener(this);
bimg1 = new BufferedImage(img.getWidth(this), img.getHeight(this),
BufferedImage.TYPE_INT_ARGB);
bimg2 = new BufferedImage(img.getWidth(this), img.getHeight(this),
BufferedImage.TYPE_INT_ARGB);
Graphics2D g2D1 = bimg1.createGraphics();
Graphics2D g2D2 = bimg2.createGraphics();
g2D1.drawImage(img, 0, 0, this);
g2D2.drawImage(img, 0, 0, this);
g2D2.drawRect(1, 1, img.getWidth(this) - 3, img.getHeight(this) - 3);
}
public void paintComponent(Graphics g){
super.painComponent(g);
Graphics2D g2D = (Graphics2D)g;
if (upState)
g2D.drawImage(bimg1, x, y, this);
else
g2D.drawImage(bimg2.x, y, this);
}
public void mousePress(MouseEvent e){
if (e.getX() >= x && e.getX() < x + bimg1.getWidth(this) && e.getY() >= y&& e.getY() < y + bimg1.getHeight(this)){
upstate = false;
setCursor(Cursor.getPredefinedCursor(Coursor.HAND_CURSOR));
dx = e.getX() - x;
dy = e.getY() - y;
repain();
}
}
public void mouseExited(MouseEvent e){}
public void mouseClicked(MouseEvent e){}
public void mouseEntered(MouseEvent e){}
public void MouseReleased(MouseEvent e){
this.setCursor(Cursor.getpredefinedCursor(Cursor.DEFAULT_CURSOR));
upState = true;
repaint();
}
public void mouseMoved(MouseEvent e){}
public void mouseDragged(MouseEvent e){
if (!upState){
x = e.getX() - dx;
y = e.getY() - dy;
repaint();
}
}
}
程序要创建缓冲区图像,需要引入java.awt.image包中的BufferedImage类。要创建一个缓冲区图,可以调用createImage()方法,该方法返回一个Image对象,然后再将它转换成一个BufferedImage对象。例如,代码:
BufferedImage bimage = (BufferedImage)this.createImage(this.getWidth(),this.getHeight());
也可利用以下构造方法来建立。
BufferedImage(int width,int heigh, int imageType);
其中参数 imageType是图像类型。
使用缓冲区显示图像,需先在缓冲区中准备好图像,再将缓冲区中的图像显示在界面上。显示图像需要图形对象Graphics,可以通过以下方法建立:
Graphics2D g2d = bimge.createGraphics();
0
投稿
猜你喜欢
- Java 执行 JS 脚本工具用途:为了便于系统扩展,提供了 JS 脚本的功能,可以通过在系统中执行脚本来获得更复杂的功能。例如:系统提供了
- using System.Runtime.InteropServices; using System.Text; publicclass F
- 🍊一. 为什么需要线程通信线程是并发并行的执行,表现出来是线程随机执行,但是我们在实际应用中对线程的执行顺序是有要求的,这就需要用到线程通信
- 计算两点之间的距离然后在控制台输出,这个题目还是挺简单的。下面我们来看看具体代码。package com.swift;import java
- 以下共有4个函数分别是:1.从剪切板获得文字。2.将字符串复制到剪切板。3.从剪切板获得图片。4.复制图片到剪切板。/** * 从剪切板获得
- 一 前言学习微服务要从基础的架构学起,首先你要有个微服务的概念才能学习对吧!!如果你都不知道啥是微服务,就一头扎进去学习,你自己也觉得自己也
- 最近有个粉丝提了个问题,说他在Spring Security中用JWT做退出登录的时无法获取当前用户,导致无法证明“我就是要退出的那个我”,
- 1.什么是单例模式?所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对
- ButterKnife的最新版本是8.4.0。首先,需要导入ButterKnife的jar包。在AndroidStudio中,File-&g
- 1.概述我们之前讨论过Java Generics的基础知识。在本文中,我们将了解Java中的通用构造函数。 泛型构造函数是至少需要有一个泛型
- 0x01 创建要转换的类和主函数注意这里一定要实现序列化package day1; import java.io.Serializable;
- 话不多说,请看代码:string xmlFilePath = "D:\\log_xml\\MarInfo.xml"; /
- MultipartResolver和ServletFileUpload冲突如果同时使用了MultipartResolver 和Servlet
- Android 集成FlutterFlutter 作为 Google 开源的新一代跨平台、高性能 UI 框架,旨在帮助开发者高效地构建出跨平
- java 使用foreach遍历集合元素的实例1 代码示例import java.util.*; public class ForeachT
- 这个工具比较简单,用于配合另外一个工具进行文件传送,废话少说,上代码import java.net.URL;import java.net.
- Android开发中,难免会遇到需要加解密一些数据内容存到本地文件、或者通过网络传输到其他服务器和设备的问题,但并不是使用了加密就绝对安全了
- 使用范围synchronized使用上用于同步方法或者同步代码块在锁实现上是基于对象去实现使用中用于对static修饰的便是class类锁使
- 本文实例讲述了C#创建windows系统用户的方法。分享给大家供大家参考。具体如下:下面的代码可以通过c#创建一个windows的本地系统账
- * String类是不可变类,只要对String进行修改,都会导致新的对象生成。* StringBuffer和StringBuilder都是