JRubyでFilthyRichClients その6
Filthy Rich Clientsの第五章はパフォーマンスに関する話題です。
アプリの速度向上のために気をつけることが書かれています。
クリッピング
与えられたクリッピングの中だけで描画を行うようにする。
# クリッピングを使わないコード def paintComponent(g) g.setColor(Color::BLACK) g.fillRect(0, 0, getWidth, getHeight) end # クリッピングを使ったコード def paintComponent(g) g.setColor(Color::BLACK) clip = g.getClipBounds g.fillRect(clip.x, clip.y, clip.width, clip.height) end
でも、クリッピングを簡単に使えないときは、無理に使う必要は無いみたい。
中間画像
画像に何度も同じ加工をしなければいけない時は、最初に画像を加工したら、加工した画像を取っておく。2回目以降は、取っておいた画像をdrawImageでコピーして使う。毎回画像を加工するより、コピーするほうが速い。
互換画像
実行している環境に最適化された画像を内部でもっておけば速い。画像を互換画像に変換して、互換画像のほうを使うようにする。
画像を互換画像に変換するmoduleをJRubyで書いてみた。
require 'java' module MakeCompatibleImage import 'java.awt.GraphicsEnvironment' module_function def get_configuration GraphicsEnvironment.getLocalGraphicsEnvironment.getDefaultScreenDevice.getDefaultConfiguration end # 与えられた幅、高さ、透明度を持つ互換画像を作成する。 # transparencyは、BufferedImage#getTransparencyで取得するか、以下の定数を指定できる。 # java.awt.Transparency::BITMASK # java.awt.Transparency::OPAQUE # java.awt.Transparency::TRANSLUCENT # http://java.sun.com/j2se/1.5.0/ja/docs/ja/api/java/awt/Transparency.html def create_compatible_image(width, height, transparency) get_configuration.createCompatibleImage(width, height, transparency) end # 与えられた画像が、互換画像であるか調べる。 def compatible_image?(image) image.getColorModel.equals(get_configuration.getColorModel) end # ソース画像をコピーした、新しい互換画像を作成する。 # 既にソース画像が互換の場合は、ソース画像を返す。 def to_compatible_image(image) return image if compatible_image?(image) compatible_image = create_compatible_image(image.getWidth, image.getHeight, image.getTransparency) g = compatible_image.getGraphics g.drawImage(image, 0, 0, nil) g.dispose compatible_image end # 引数で指定された画像へのパスから、互換画像を作成する。 # パスはURLかファイル名を指定する。 # ex: # MakeCompatibleImage.load_compatible_image("http://sample.com/foo.png") # MakeCompatibleImage.load_compatible_image("foo.png") def load_compatible_image(path) klass = fetch_resource_class(path) image = javax.imageio.ImageIO.read(klass.new(path)) to_compatible_image(image) end def fetch_resource_class(path) return java.net.URL if path =~ %r!^http://! java.io.File end end if __FILE__ == $0 include_class 'java.awt.image.BufferedImage' p MakeCompatibleImage.get_configuration img = BufferedImage.new(100, 50, BufferedImage::TYPE_INT_ARGB) p MakeCompatibleImage.create_compatible_image(img.getWidth, img.getHeight, img.getTransparency) [BufferedImage::TYPE_INT_ARGB, BufferedImage::TYPE_INT_RGB].each do |type| image = BufferedImage.new(100, 50, type) print "compatible_image?:" p MakeCompatibleImage.compatible_image?(image) p image p MakeCompatibleImage.to_compatible_image(image) p "" end end
書いたんだけど、JavaのImageIOで、URLオブジェクトからimageを作ろうとすると例外が飛ぶ。
Fileだと上手くいくんだけど。。。↓のように単純化してもエラーになるんだけど、なんでだろ。。
image = javax.imageio.ImageIO.read java.net.URL.new("http://www.google.co.jp/images/srpr/nav_logo13.png")
javax.imageio.ImageIO:-1:in `createImageInputStream': javax.imageio.IIOException: Can't create cache file! (NativeException) from javax.imageio.ImageIO:-1:in `read'