當影像資訊量較大,採用以上直接顯示的方法,可能前面一部分顯示後,顯示後面一部分時,由於後面一部分還未從文件讀出,使顯示呈現斑駁現象。為了提高顯示效果,許多應用程式都採用影像緩衝技術,即先把影像完整裝入內存,在緩衝區中繪製影像或圖形,然後將緩衝區中繪製好的影像或圖形一次性輸出在螢幕上。緩衝技術不僅可以解決閃爍問題,而且由於在電腦記憶體中建立影像,程式可以對影像進行像素級處理,完成複雜的影像變換後再顯示。
【例】小應用程式示範影像緩衝顯示技術。程式運作時,當滑鼠在影像區域內按下時,影像會出現邊框,托動滑鼠時,影像也會隨之移動。抬起滑鼠後,邊框消失。程式將兩種狀態的圖像先放入兩個緩衝區,當滑鼠拖曳時,不斷地在新的位置重繪滑鼠按下樣式的圖像滑鼠抬起時,重繪滑鼠會抬起樣式的圖像。
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.this.this(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.TY1212021 月_200 月 2012002m. createGraphics(); Graphics2D g2D2 = bimg2.createGraphics(); g2D1.drawImage(img, 0, 0, this); g2D2.drawImage(img, 0, 0, this); g2D2.drawRect(1, 1, img.Width(this) -Width(this) -Width(this) -Width(this) -Width(this) -Width 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(bimg1, x, y, this); else g2D.drawImage(bimg2. ); } 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 e){} = 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();