ImageResizeはImageMagickなどの外部プログラムに依存せずに、単体で画像をリサイズできる。ただしJavaの実行環境が必要。


SFCの「革新的ネットサービスの構築」という授業のTAをやっていて、昨日と今日niftyに行って開発合宿をしていた。
そこでいろいろあって、ImageMagickなしで画像のサムネイルを作る方法が無いのか模索していたら、ImageResizeというgemができた。

■インストール

gem install ImageResize


■使う
require 'rubygems'
require 'ImageResize'

# input, output, width, height
Image.resize('big.jpg', 'small.jpg', 40, 40)
これで40×40ピクセルに縮小される。
縦横のアスペクト比が1:1ではない画像の場合、アスペクト比を保ったまま長辺の方にあわせて縮小する。


■ソースコード
githubに置いた。
http://github.com/shokai/ImageResize-ruby


■実装
本体はJava。
標準実行環境にJPEGやGIFやBITMAPなど様々な画像フォーマットの読み書き機能を含んでいる環境というと、Javaと.NETとopenFrameworksしか思いつかなかった。
その中でいちばん色々なマシンにインストールされていそうで、配布が容易な物を選んだらJavaになった。


Javaでの画像の扱いは.NET並に簡単。java.awtとjavax.imageioの下に色々充実しているのでそれらを使えばいい。
ImageResize.java

import javax.imageio.*;
import java.io.*;
import java.awt.image.*;
import java.awt.geom.*;
import java.awt.image.*;
import java.util.regex.*;

class ImageResize{

    public ImageResize(){
    }

    public static void main(String args[]){
if(args.length < 4){
    System.out.println("ImageResize in.jpg out.jpg 320 320");
    System.exit(1);
}
ImageResize app = new ImageResize();
if(app.resize(args[0], args[1], Integer.parseInt(args[2]), Integer.parseInt(args[3]))){
    System.out.println(args[1]);
}
    }

    public boolean resize(String fname_in, String fname_out, int max_width, int max_height){
System.out.println(fname_in);
BufferedImage img = null;
try {
    img = ImageIO.read(new File(fname_in));
}
catch (Exception e) {
    e.printStackTrace();
    img = null;
}

int width, height;
if(img.getWidth() < img.getHeight()){
    height = max_height;
    width = img.getWidth() * max_height / img.getHeight();
}
else{
    width = max_width;
    height = img.getHeight() * max_width / img.getWidth();
}
System.out.println(img.getWidth() + "x" +img.getHeight() + " => " + width + "x" + height);

BufferedImage img_resized = new BufferedImage(width, height, img.getType());
AffineTransformOp ato = new AffineTransformOp(AffineTransform.getScaleInstance((double)width / img.getWidth(), 
       (double)height / img.getHeight()), 
      null);
ato.filter(img, img_resized);


String format = Pattern.compile("^.+\\.(.+)$").matcher(fname_out).replaceAll("$1");
boolean result = false;
try {
    result = ImageIO.write(img_resized, format, new File(fname_out));
}
catch (Exception e) {
    e.printStackTrace();
    result = false;
}
return result;
    }
    
}


■参考


今回は使わなかったが、Java Advanced Imaging (JAI) APIというのが標準実行環境には含まれていないけどSunが作っていて、かなり充実しているらしい。
Javaランタイムも速くなってきているらしいしScalaで画像処理とかしてみたい。