當圖像信息量較大,采用以上直接顯示的方法,可能前面一部分顯示后,顯示后面一部分時,由于后面一部分還未從文件讀出,使顯示呈斑駁現象。為了提高顯示效果,許多應用程序都采用圖像緩沖技術,即先把圖像完整裝入內存,在緩沖區中繪制圖像或圖形,然后將緩沖區中繪制好的圖像或圖形一次性輸出在屏幕上。緩沖技術不僅可以解決閃爍問題,并且由于在計算機內存中創建圖像,程序可以對圖像進行像素級處理,完成復雜的圖像變換后再顯示。
【例】小應用程序程序演示圖像緩沖顯示技術。程序運行時,當鼠標在圖像區域內按下時,圖像會出現邊框,托動鼠標時,圖像也隨之移動。抬起鼠標后,邊框消失。程序將兩種狀態的圖像先放入兩個緩沖區,當鼠標拖動時,不斷地在新的位置重繪鼠標按下樣式的圖像鼠標抬起時,重繪鼠標抬起樣式的圖像。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
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對象。例如,代碼:
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(); |