Compositeで複数の画像を結合する

Webアプリのパフォーマンスを向上させるためには、いろいろな方法がありますが

小さいアイコンに大量のアクセスが発生して負荷が高くなるのを避けるために、複数の画像をまとめるのは効果的です。
(特に、Google App Engine(GAE)の場合、CPUの負荷が一番コストがかかるため)

GAEのImageライブラリーのCompositeを使えば、複数の画像を簡単にまとめることができます。
あとで、切り出すことを考えると、なるべく画像の大きさはすべて同じにした方がいいでしょう。

GAEで複数の画像をまとめる方法

同じ画像を横に3つ並べる

画像のbyte[] をBlogとかから、取り出す。画像のサイズは200x200の固定とする
    Image img=ImagesServiceFactory.makeImage(imagebytes);    //imageのバイト
  List<Composite> composites=new ArrayList<Composite>();
    for(int i=0;i<3;i++){
composites.add(ImagesServiceFactory.makeComposite(img, 200*i, 0, 1, Composite.Anchor.TOP_LEFT));
    }
    long bgColor=0;//transparent, if you wish white,0xFFFFFFFFL
    ImagesService imagesService = ImagesServiceFactory.getImagesService();
    Image mixed=imagesService.composite(composites, 200*3, 200, bgColor, OutputEncoding.PNG);

ImagesServiceFactoryを使ってbyte配列からImageにする。

Compositeを作る。Compositeの引数が少しわかりにくいが、画像・X座標・Y座標・透明度・アンカーとなる。
(アンカーはいろいろなことができますが、単純に画像並べるだけだとTOP_LEFT以外は気にしない方がいい)

この場合、3つ並べるので、X座標は画像の幅である200にiを掛けている。y座標は0になる。
透明度は、元のままなので1となる

ImagesService を使って、合成させます。
この時の引数が、Compositeのリスト・混合後の画像の横幅、混合後の画像の縦幅・混合後の画像の背景色・出力形式となります。

背景を透明にする場合は、 0になり、白とかにするなら、アルファーも指定した 0xFFFFFFFFL になる。
この場合、200x200の画像が横に3つ並ぶので、600x200を指定しています。

後は、完成した画像から、getImageData()して、Datastoreに保存したり、出力したりします。

複数のレイヤー画像を混合する

上記と例で、Composite作成時に、x座標を0のままにします。
レイヤーごとに透明度を調整してもいいでしょう。
composites.add(ImagesServiceFactory.makeComposite(img,0, 0, 1, Composite.Anchor.TOP_LEFT));

imagesServiceで結合時に、画像サイズを元と同じにすれば、レイヤーが混合された画像ができます。


注意事項

画像の結合はバグ#2645 で透明度が反映されないことがありました。
SDK 1.7.0でも、ローカルの開発サーバーだと透明色が黒になるような。(サーバー側は問題ないですが)
#1417ではFixとなっていますが

Comments