<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    鷹翔宇空

    學習和生活

    BlogJava 首頁 新隨筆 聯系 聚合 管理
      110 Posts :: 141 Stories :: 315 Comments :: 1 Trackbacks
    以前寫過2篇關于AWT中圖像加載顯示方法的文章,最近又多了一些對于 ImageProducer / ImagConsumer 模式的一些理解,嘗試著用文字總結了一下,接著還想再寫一篇介紹 AWT 中圖像過濾的原理和方法。你可能認為現在學習 AWT 中的成像方法對于開發中已經沒有太大的意義,因為已經有了 Java 2D 和 JAI ,但是我在實際工作中感到還是無法完全離開 AWT,特別是在一些基本的應用上。而且我覺得理解 AWT 的 Producer / Consumer (push) model 對于理解 Java 2D 的 Immediate mode model 和 JAI 的 Pipeline (pull) model 的都是有好處的。

    因為水平有限,這方面學習資料相對也不豐富,我也不知道我的理解或想法是否完全正確或者表述清楚,感興趣的朋友可以當作學習參考,希望能夠和我聯系進行進一步的討論。



    AWT 使用 ImageProducer / ImagConsumer 模式,支持加載和顯示 GIF 圖像文件格式和 JPEG 圖像文件格式。因為圖像的加載和顯示是異步方式進行的,所以有大量加載和顯示的技術。

    在 AWT 中,提供了一個 java.awt.Image 類。java.awt.Image 類代表一個圖像對象被作為參數傳遞給其他用來顯示和處理圖像的其他 AWT 對象使用。例如,通過調用 Graphics.drawImage(java.awt.Image, int, int, ImageObserver) 方法,可以在組件中畫出圖像。

    java.awt.Image 是一個定義方法的抽象類,它定義的方法提供的對圖像信息的訪問。而創建和處理圖像的基本結構則在 java.awt.image 包中。注意,這里不要和 java.awt.Image 發生混淆。

    AWT? 加載和顯示圖像使用的是 ImageProducer / ImagConsumer 模式,我們必須了解3個術語,ImageProducer(圖像生產者),ImageConsumer(圖像消費者)和ImageObserver(圖像觀察者)。

    ImageProducer 負責生產圖像的位,ImagConsumer 接受圖像的位,ImageObserver 監視 ImageProducer 的圖像生產過程。ImageProducer 生產傳遞給 ImagConsumer 與圖像相關的位。因為圖像生產過程是異步進行的,并不是一次性生產所有圖像位,所以當 ImageProducer 加載圖像時,ImageObserver 用來監視它的進展情況。因為 java.awt.Component 實現了 ImageObserver 接口,所以 AWT 中的每個組件都可以是ImageObserver,當一個給定的 ImageProducer 進行異步操作時,這個 ImageObserver 可以選擇是否被更新。java.awt.image 包為 ImageProducer,ImagConsumer 和 ImageObserver 都定義了接口。

    ImageProducer
    和圖像相關的位并不存儲在 java.awt.Image 中,每個圖像都維護一個和一個 ImageProducer?的關聯。這個 ImageProducer?的責任是生產圖像的位并將它們傳送給 ImagConsumer,用于過濾該圖像。

    java.awt.image軟件包中,FilteredImageSource(被過濾的圖像源)和 MemoryImageSource(內存的圖像源)實現了 ImageProducer? 接口,是 ImageProducer?。


    ImagConsumer
    java.awt.image軟件包中,ImageFilter(圖像過濾器)和 PixelGrabber(像素抓取器)實現了 ImagConsumer 接口,是 ImagConsumer。


    ImageProducer?和 ImagConsumer 的詳細介紹請閱讀 使用 ImageProducer? / ImagConsumer 進行圖像過濾


    ImageObserver
    ImageObserver接口中,定義了一個常數集合和一個方法:

    public boolean imageUpdate(image img, int flags, int x, int y, int width, int height);

    ImageObserver的常數
    標志 含義
    ABORT 圖像加載被中斷
    ALLBITS 所有的位都已加載給圖像
    ERROR 在加載過程中發生錯誤
    FRAMEBITS 多幀圖像的一個幀被傳送,一般用于GIF
    HEIGHT 圖像的高度已經可用
    PROPERTIES 圖像的屬性已經可用
    SOMEBITS 圖像的縮放變體的多個位已經可用
    WIDTH 圖像的寬度已經可用

    參數 flags 的作用是通知圖像觀察者圖像生產的進展情況。這些常數代表傳遞給 ImageObserver.imageUpdate() 的 flags 參數中的位。

    當 Component 作為 ImageObserver 時,一旦圖像有新的部分被加載,就會調用 Component.imageUpdate() 方法,imageUpdate() 再調用 repaint() 重新繪制圖像。repaint() 將先調用 update() 方法清除組件背景,再由 update() 方法調用 paint() 方法繪制圖像。我們可以通過重載 imageUpdate() 方法控制組件何時被更新,重載 update() 方法控制是否每次重繪都要清除背景圖像(每次重繪都清除背景圖像會造成畫面閃爍)。


    為了更好的理解,下面我們來看幾個樣例程序:

    例1,圖像位在需要之前不被生產
    import?java.net.URL;
    import?java.applet.Applet;
    import?java.awt.Graphics;
    import?java.awt.Image;

    public?class?ImageTestAppletSimple?extends?Applet{
    ????
    private?Image?im;
    ????
    ????
    public?void?init(){
    ????????URL?codebase?
    =?getCodeBase();
    ????????System.out.println(codebase);
    ????????
    ????????im?
    =?getImage(codebase,"flower.jpg");
    ????????
    ????????System.out.print(
    "Image?width?=?"?+?im.getWidth(this));
    ????????System.out.println(
    " hight?=?"?+?im.getHeight(this));
    ????}

    ????
    ????
    public?void?paint(Graphics?g){
    ????????g.drawImage(im,
    0,0,this);
    ????}

    }

    輸出結果:
    image width = -1 height = -1

    圖像的高度和寬度只有在圖像被完全加載后才是有效的,輸出結果說明 java.awt.image 相關的圖像位在需要之前不被生產。


    例2,圖像異步生產

    import?java.net.URL;
    import?java.applet.Applet;
    import?java.awt.Graphics;
    import?java.awt.Image;

    public?class?ImageTestAppletSimple2?extends?Applet{
    ????
    private?Image?im;
    ????
    ????
    public?void?init(){
    ????????im?
    =?getImage(getCodeBase(),"flower.jpg");
    ????}

    ????
    ????
    public?void?paint(Graphics?g){
    ????????System.out.println(
    "drawing?image...");
    ????????System.out.println(g.drawImage(im,
    0,0,this));
    ????}

    }

    輸出結果:
    drawing?image...
    false
    drawing?image...
    false
    drawing?image...
    false
    drawing?image...
    true

    輸出結果說明組件作為 ImageObserver ,監視 ImageProducer 異步生產圖像,一旦有新的圖像位被生產時就重繪圖像,圖像完全加載后 drawImage() 方法返回 true。


    例3,重載 ImageObserver 的 imageUpdate() 方法,在圖像完全加載前不調用 repaint()

    import?java.applet.Applet;
    import?java.awt.Graphics;
    import?java.awt.Image;

    public?class?ImageTestAppletWithUpdate?extends?Applet{
    ????
    private?Image?im;
    ????
    ????
    public?void?init(){
    ????????im?
    =?getImage(getCodeBase(),"flower.jpg");
    ????????
    ????????System.out.print(
    "Image?width?=?"?+?im.getWidth(this));
    ????????System.out.println(
    "hight?=?"?+?im.getHeight(this));
    ????}

    ????
    ????
    public?void?paint(Graphics?g){
    ????????g.drawImage(im,
    0,0,this);
    ????}

    ????
    ????
    public?boolean?imageUpdate(Image?image,int?flags,int?x,int?y,int?w,int?h){
    ????????System.out.println(
    "imageUpdate():x="?+?x?+?",y="?+?y?+?",w="?+?w?+?",h="?+?h);
    ????????
    ????????
    if((flags?&?ALLBITS)?==?0)
    ????????????
    return?true;
    ????????
    else
    ????????
    {
    ????????????repaint();
    ????????????
    return?false;
    ????????}

    ????}

    }



    例4,重載? Component.update() 方法,被調用時不清除背景圖像,直接調用 paint() 方法繪制圖像,消除閃爍

    import?java.applet.Applet;
    import?java.awt.Graphics;
    import?java.awt.Image;

    public?class?ImageTestAppletWithSmoothDynamicUpdate?extends?Applet{
    ????
    private?Image?im;
    ????
    ????
    public?void?init(){
    ????????im?
    =?getImage(getCodeBase(),"hl.jpg");
    ????????
    ????????System.out.print(
    "Image?width?=?"?+?im.getWidth(this));
    ????????System.out.println(
    "hight?=?"?+?im.getHeight(this));
    ????}

    ????
    ????
    public?void?paint(Graphics?g){
    ????????g.drawImage(im,
    0,0,this);
    ????}

    ????
    ????
    public?boolean?imageUpdate(Image?image,int?flags,int?x,int?y,int?w,int?h){
    ????????System.out.println(
    "imageUpdate():x="?+?x?+?",y="?+?y?+?",w="?+?w?+?",h="?+?h);
    ????????
    ????????repaint();
    ????????
    ????????
    if((flags?&?ALLBITS)?==?0)
    ????????????
    return?true;
    ????????
    else
    ????????????
    return?false;
    ????}

    ????
    ????
    public?void?update(Graphics?g){
    ????????paint(g);
    ????}

    }
    posted on 2006-02-15 16:39 TrampEagle 閱讀(1198) 評論(0)  編輯  收藏 所屬分類: java
    主站蜘蛛池模板: 亚洲一卡二卡三卡四卡无卡麻豆| 午夜爱爱免费视频| 2022国内精品免费福利视频| 亚洲精品视频免费| 又粗又硬又大又爽免费视频播放| 亚洲精品字幕在线观看| 亚洲午夜久久影院| 亚洲AV成人一区二区三区在线看| 免费又黄又爽又猛大片午夜| 色猫咪免费人成网站在线观看| 永久免费AV无码国产网站| 亚洲精品国产成人影院| 激情内射亚洲一区二区三区| 亚洲成av人影院| 亚洲久热无码av中文字幕| av电影在线免费看| 亚洲国产精品VA在线看黑人| 日本在线免费播放| 亚洲国产成人VA在线观看| 亚洲成AV人片久久| 精品免费tv久久久久久久| 日本人的色道www免费一区| 久久夜色精品国产嚕嚕亚洲av| 亚洲人成网网址在线看| 无码日韩精品一区二区免费暖暖| 亚洲综合在线成人一区| 国产成人AV片无码免费| 亚洲乱码在线播放| 亚洲av区一区二区三| 亚洲爆乳精品无码一区二区| 亚色九九九全国免费视频| 日韩亚洲一区二区三区| 成人黄色免费网站| 亚洲网址在线观看你懂的| 蜜桃视频在线观看免费网址入口| 亚洲成综合人影院在院播放| 午夜小视频免费观看| 亚洲videos| 亚洲成AV人网址| 亚洲免费福利在线视频| 九九全国免费视频|