以前GridViewに画像をたくさん並べる方法
のときにサムネイル化するために
画像を縮小する必要があったのだけど、
あまり考えずに
Google App Engine で以下のようなServletを書いて
処理していた。
public class ResizeServlet extends HttpServlet {
private static final long serialVersionUID = -999999L;
/** デフォルトの高さ(ピクセル) */ public static final int HEIGHT = 50;
/** ロガー */ private static final Logger log = Logger.getLogger(ResizeServlet.class.getName()); /** * 生存確認 */ public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { PrintWriter pw = resp.getWriter(); pw.print("ResizeServlet is alive!"); pw.close(); } /** * 画像を高さ100spに変更して戻す */ public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException{ DataInputStream dis = new DataInputStream(req.getInputStream()); ByteArrayOutputStream baos = new ByteArrayOutputStream(); int c; while((c = dis.read())!=-1){ baos.write(c); } byte[] org = baos.toByteArray(); log.info("doPost: length=" + org.length); Image image = ImagesServiceFactory.makeImage(org); int height = image.getHeight(); int width = image.getWidth(); Transform resizer = ImagesServiceFactory.makeResize( (int)(((double)width*HEIGHT)/((double)height)), HEIGHT); ImagesService service = ImagesServiceFactory.getImagesService(); byte[] result = service.applyTransform(resizer, image).getImageData(); DataOutputStream dos = new DataOutputStream(resp.getOutputStream()); dos.write(result, 0, result.length); dos.close(); dis.close(); }}App Engineの上記のServletサイトへPOSTで送った画像を
App Engineに用意されているGoogle APIで高さ100ptの画像に変換して
送信元へ返しているだけの単純なつくりだ。
実際にはパラメータで高さ指定できるものを利用しているが
サンプルコードは決め打ちにしてある。
ちなみに、Android側はURLConnectionを使ってbyte[]でもらってくればいい。
private byte[] resizeImage(String url, byte[] org) throws IOException{
URLConnection conn = new URL(url).openConnection();
Log.d(TAG, "getImage: url =" + url);
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setRequestProperty("Content-Type", "application/octet-stream");
conn.setRequestProperty("User-Agent", "androidSample");
conn.setRequestProperty("Content-Length",
new Integer(org.length).toString());
// 送信
OutputStream os = conn.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
dos.write(org, 0, org.length);
// 受信
InputStream is = conn.getInputStream();
DataInputStream dis = new DataInputStream(is);
int b;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
while((b = dis.read())!=-1){
baos.write(b);
}
dis.close();
is.close();
dos.close();
os.close();
byte[] result = baos.toByteArray();
Log.d(TAG, "resize: org_length=" + org.length + ", result_length=" +
result.length);
return result;
}
引数の変数urlは先のApp Engineの該当ServletのURLを
書けば良い。
カメラにせよ、S3上にせよ画像データをbyte[]で渡してやれば
戻り値として小さくなった画像を返してくれる。
これを非同期でGridLayoutを更新させるように実装すればいい。
#ボタンイベントなどに書くと、とたん固まってしまうから、やらないほうがいい
#とりあえず動けばいい人は書いてもいいが..
けれど、
昨日Androidの会のMLに以下のようないくつかの方法が
紹介されていた。
画像をきれいに縮小する方法
まだ試してはいないけれども
これだと通信事情が悪い場所でも
縮小できそうだ。
画像に関する知識が私にはまったくなかったので
ありもの(AppEngineのImageService)で何とかしようとしていたけど、
質問した人は画像処理について詳しい方のようで
もっといい方法を紹介してくれている。
勉強になった。
0 件のコメント:
コメントを投稿