SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Groovy+GrailsでRailsなWeb開発

GroovyとGoogle App Engineでアプリ開発(番外編)
~GAEで利用できるさまざまなサービス

Groovy+GrailsでRailsなWeb開発 第8回


  • X ポスト
  • このエントリーをはてなブックマークに追加

イメージ処理

 Googleのサービスの中に「Picasa」というアルバムアプリケーションがあります。このPicasaで使われているイメージ処理の機能も、GAE/Jから利用できます。では、今度はイメージを生成し出力するサーブレットを定義し、それを利用してみることにしましょう。「src」内に「ImageServlet.groovy」ファイルを作成し、次のようにソースコードを記述します。

「ImageServlet.groovy」ファイルの内容
import java.lang.Exception
import java.io.*
import javax.servlet.*
import javax.servlet.http.*
import com.google.appengine.api.images.*
import java.util.logging.Logger

class ImageServlet extends HttpServlet {
    private static final Logger log = Logger.getLogger(ImageServlet.class.getName())
   
    void doGet(HttpServletRequest request, HttpServletResponse response)
            throws IOException {
        ServletContext context = this.getServletContext()
        response.contentType = "image/jpeg"
        String fname = request.getParameter("image")
        String fpath = "/WEB-INF/img/" + fname + ".jpg"
        byte[] data2 = this.getImageByte(context,fpath)
        Image img = this.getImage(data2)
       
        if (img != null){
            Image img2 = this.transformImage(request,img)
            BufferedOutputStream bout = null
            try {
                ServletOutputStream out = response.getOutputStream()
                bout = new BufferedOutputStream(out)
                byte[] data = img2.getImageData()
                int len = data.length;
                for(int i = 0;i < data.length;i++){
                    bout.write(data[i])
                }
                out.flush()
                out.close()
            } catch(e){
                log.warning(e.message)
            }
        }
    }
   
    // イメージファイルを読み込みbyte配列を返す
    byte[] getImageByte(ServletContext context,String fpath){
        BufferedInputStream bin = null
        ByteArrayOutputStream bout = null
        Image img = null
        byte[] data = null;
        try {
            InputStream fin = context.getResourceAsStream(fpath)
            bin = new BufferedInputStream(fin)
            bout = new ByteArrayOutputStream()
            while(true){
                int n = bin.read()
                if (n == -1) break
                bout.write(n)
            }
            data = bout.toByteArray()
            bout.close()
            bin.close()
        } catch(e){
            log.warning(e.message)
        }
        return data
    }
   
    // byte配列からImageインスタンスを生成し返す
    Image getImage(byte[] data){
        int n = data.length
        return ImagesServiceFactory.makeImage(data)
    }
   
    // イメージを指定した大きさに拡大縮小したものを返す
    Image transformImage(HttpServletRequest request,Image img){
        int w = 100
        int h = 100
        try {
            w = Integer.parseInt(request.getParameter("w"))
        } catch(e){
            log.warning(e.message)
        }
        try {
            h = Integer.parseInt(request.getParameter("h"))
        } catch(e){
            log.warning(e.message)
        }
        Transform resize = ImagesServiceFactory.makeResize(w, h)
        ImagesService service = ImagesServiceFactory.getImagesService()
        return service.applyTransform(resize, img)
    }
}

 作成したら、このサーブレットをweb.xmlに登録しておきます。<web-app>内に、次のようにタグを追記してください。これで「/image」というURIで登録されます。

ImageServletを/imageというURIに割り付ける
<servlet>
    <servlet-name>ImageServlet</servlet-name>
    <servlet-class>ImageServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>ImageServlet</servlet-name>
    <url-pattern>/image</url-pattern>
</servlet-mapping>
image?image=image1&w=250&h=250とパラメータを指定してアクセスすると、image1.jpgが指定された大きさに拡大縮小され表示される。
image?image=image1&w=250&h=250とパラメータを指定してアクセスすると、image1.jpgが指定された大きさに拡大縮小され表示される。

 これで完成です。このサーブレットは、imgwhといったパラメータで表示するイメージの名前・横幅・縦幅を指定します。実際に試してみましょう。「WEB-INF」内に、新たに「img」というフォルダを作成し、その中に「image1.jpg」というイメージファイルを用意しておきます。そして、「ドメイン/image?image=image1&w=250&h=250」というようにURLを指定してアクセスしてください。「image1.jpg」が縦横250ドットの大きさ(いずれかが250ドットとなるように調整されたサイズ)に縮小されて表示されます。

 ただし、実際にGoogleサイトにデプロイして動作を確認してみると、あまり実用的ではありません。表示する速度があまりに遅いのです。ソースコードを見てみれば分かるように、すべてのデータの出力部分を1バイトごとに行っていることが関係しているでしょう。GAE/JのAPIには、byte配列をまとめて出力するメソッドもサポートされているのですが、いろいろ試してみたところ、Groovyでこれを行おうとすると、ClassLoaderの取得部分でaccess deniedと言われてしまうようです。これは筆者の環境かバージョンによる問題なのかもしれませんが、もしGroovy固有の問題とすると、いずれ改善されることを期待するしかないでしょう。

次のページ
イメージ処理について

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
Groovy+GrailsでRailsなWeb開発連載記事一覧

もっと読む

この記事の著者

掌田 津耶乃(ショウダ ツヤノ)

三文ライター&三流プログラマ。主にビギナーに向けたプログラミング関連の執筆を中心に活動している。※現在、入門ドキュメントサイト「libro」、カード型学習サイト「CARD.tuyano.com」を公開...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/4400 2009/10/09 20:27

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング