Images Java APIを実行する
これまでの手順で、ライブラリの準備ができましたので、サーバサイドのプログラムを書いていきたいと思います。処理内容は、最初に説明したのと同じ拡大/縮小処理です。
package com.daisukeyamashita.test.images;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import com.google.appengine.api.images.Image;
import com.google.appengine.api.images.ImagesService;
import com.google.appengine.api.images.ImagesServiceFactory;
import com.google.appengine.api.images.Transform;
import com.google.appengine.api.images.ImagesService.OutputEncoding;
@SuppressWarnings("serial")
public class ImageTestServlet extends HttpServlet {
@SuppressWarnings("unchecked")
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
MemoryFileItemFactory factory = new MemoryFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
resp.setContentType("image/png");
OutputStream out = resp.getOutputStream();
try {
List<FileItem> list = upload.parseRequest(req);
for (FileItem item : list) {
if (!(item.isFormField())) {
String fileName = item.getName();
if (fileName != null && !"".equals(fileName)) {
int size = (int) item.getSize();
byte[] data = new byte[size];
InputStream in = item.getInputStream();
in.read(data);
ImagesService imagesService = ImagesServiceFactory.getImagesService(); //(1)
Image oldImage = ImagesServiceFactory.makeImage(data); //(2)
Transform resize = ImagesServiceFactory.makeResize(300, 50); //(3)
Image newImage = imagesService.applyTransform(resize, oldImage,
OutputEncoding.PNG); //(4)
byte[] newImageData = newImage.getImageData();
out.write(newImageData);
out.flush();
}
}
}
} catch (FileUploadException e) {
e.printStackTrace();
} finally {
if (out != null) {
out.close();
}
}
}
}
サーバサイドの処理が完成しましたので、クライアント側のHTMLを用意したいと思います。「war/index.html」を以下のように書き換えて下さい。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <title>Hello App Engine</title> </head> <body> <h1>Hello Google App Engine for Java with Images Java API!!!</h1> <form method="POST" enctype="multipart/form-data" action="imagetest"> <input type="file" name="file" /></br> <input type="submit" value="upload" /> </form> </body> </html>
これで、すべての準備が整いました。プロジェクト名を右クリックして、[Run As]-[Web Application]を選択してください。

Consoleに以下のように表示されればローカルサーバの起動が完了です。好きなブラウザで「http://localhost:8080/」にアクセスしてみましょう。

前回、表示されていた簡易ブラウザはGWTのデバッグ専用ブラウザですので、今回のようにGWTを利用しないプロジェクトでは起動しません。
以下のように表示されていればOKです。[ファイルを選択]ボタンをクリックして、手元にある画像ファイルを選択してから、[upload]ボタンをクリックします。

画像が縮小されているのを確認できるかと思います。

| 目的 | メソッド | 備考 |
| サイズ変更 | makeResize(int width, int height) | width : 幅 height : 高さ |
| 縦回転 | makeVerticalFlip() | |
| 横回転 | makeHorizontalFlip() | |
| 回転 | makeRotate(int degrees) | degrees |
| 切り出し | makeCrop(double leftX, double topY, double rightX, double bottomY) makeCrop(float leftX, float topY, float rightX, float bottomY) |
leftX : 左座標 topY : 上座標 rightX : 右座標 bottomY : 下座標 |
| 画質自動調整 | makeImFeelingLucky() | この機能はローカルテストで利用できません。 |
画像の荒さが気になった方もいるかと思いますが、ローカルテスト時には画像処理をローカルマシンで実行する必要があり、本番とは別の負荷が軽い(けど荒くなる)拡大/縮小処理方法になっているためです。実際にGoogle App Engineにサービスをデプロイすると、 エッジのきれいな画像が表示されます。

まとめ
今回は画像処理を勉強しましたが、いかがでしたでしょうか? 今回の記事で、Google App EngineのImages Java API は非常に簡単に利用できるということが分かっていただけたかと思います。
Google App Engineはファイルの出力、JNI経由のネイティブプログラムが利用できないという制限がありますが、今回利用したApache CommonsライブラリのようにPure Javaで記述されたプログラムであれば、Google App Engine上で動かすことができますので、他の画像処理ライブラリを利用することでさらに高度な加工処理を実行することもできます。
興味のある方は、他のライブラリでの画像加工にも挑戦してみてはいかがでしょうか?
