- PR -

PHPで上書きした画像ファイルをJAVAアプレットに表示させたい。

投稿者投稿内容
さくらば
大ベテラン
会議室デビュー日: 2002/11/12
投稿数: 145
投稿日時: 2004-04-28 05:09
こんにちは、さくらばです。

Web を紹介してもらったので... というわけではないのですが

引用:

Makiさんの書き込み (2004-04-26 09:01) より:
getImage()に変えてImageI/Oクラスの
read(URL url)を使ったところ、アプレットを起動させる度に、
画像ファイルのロードが出来ました。



解決したということでどうでもいいかもしれませんが、個人的に腑に落ちなかったので
ちょっと調べてみました。

結局、Toolkit が static なキャッシュを持っているので、Applet が destroy しても
キャッシュが残ってしまいます。

Toolkit のコンクリートクラスの SunToolkit では getImage は次のようになっています。

コード:
    static SoftCache imgCache = new SoftCache();

    public java.awt.Image getImage(URL url) {
	return getImageFromHash(this, url);
    }

    static synchronized java.awt.Image getImageFromHash(Toolkit tk, URL url) {
       // セキュリティチェックの部分は省略

	java.awt.Image img = (java.awt.Image)imgCache.get(url);
	if (img == null) {
	    try {	
		img = tk.createImage(new URLImageSource(url));
		imgCache.put(url, img);
	    } catch (Exception e) {
	    }
	}
	return img;
    }



SoftCache は SoftReference を使用したマップになっています。
このコードからキャッシュになければ生成し、キャッシュにあればそれを利用していることが分かります。

同様なことは Applet#getImage にもあります。Applet がイメージのキャッシュをしているのではなく
Applet のコンテナである AppletContext がキャッシュをしているということが分かります。

以下は AppletViewer のコードですが Java Plug-in でも同じようなコードになっています。
Applet の getImage は AppletContext の getImage をコールしているだけになっています。
AppletContext はインタフェースなので、それを実装している AppletViewer の getImage
を見てみると次のようになっています。

コード:
    private static Map imageRefs = new HashMap();

    public Image getImage(URL url) {
	return getCachedImage(url);
    }

    static Image getCachedImage(URL url) {
	return (Image)getCachedImageRef(url).get();
    }

    static Ref getCachedImageRef(URL url) {
	synchronized (imageRefs) {
	    AppletImageRef ref = (AppletImageRef)imageRefs.get(url);
	    if (ref == null) {
		ref = new AppletImageRef(url);
		imageRefs.put(url, ref);
	    }
	    return ref;
	}
    }



static なマップにイメージをキャッシュしており、getImage はキャッシュから持ってきている
ことが分かります。

これに対して ImageIO では単純に毎回 URL#openStream から InputStream を生成して、読み込み
を行っています。

ImageIO が使えればいいのですが、使えない場合は Toolkit#getImage の代わりに Toolkit#createImage を使うようにすればいいようです。

コード:
    Image image = Toolkit.getDefaultToolkit().createImage(new URL(getCodeBase(), "0.jpg"));


Maki
会議室デビュー日: 2004/04/23
投稿数: 9
お住まい・勤務地: Kanagawa
投稿日時: 2004-04-28 11:07
引用:


static なマップにイメージをキャッシュしており、getImage はキャッシュから持ってきている
ことが分かります。

これに対して ImageIO では単純に毎回 URL#openStream から InputStream を生成して、読み込み
を行っています。

ImageIO が使えればいいのですが、使えない場合は Toolkit#getImage の代わりに Toolkit#createImage を使うようにすればいいようです。

コード:
    Image image = Toolkit.getDefaultToolkit().createImage(new URL(getCodeBase(), "0.jpg"));






さくらばさん、ありがとうございました。
getImageとキャッシュの関係がよく分かり、今後はcreateImageとの
使い分けがうまく出来そうです
これからもよろしくお願いいたします。

スキルアップ/キャリアアップ(JOB@IT)