最近はスマホのカメラの性能が上がり、その結果として画像ファイルサイズが大きくなりました。解像度が上がったことは嬉しいのですが、画像ファイルをウェブアプリなどにアップロードしようとする際に時間がかかったり、パケット通信量が増えてしまったりします。また送信先の API やシステム設定によってはアップロードサイズに上限が設定されていて、そのままでは送れなかったりすることもあります。
そんな場合に「画像を小さくしてから処理する」方法が考えられますが、Java によるその一例を紹介します。画像ファイルデータが img 変数にバイト配列で格納できているという前提で、横幅を 800 ピクセル、縦横比を変えずに高さをそれにあわせる形で変更するような処理内容を記述しています(こうすると、大抵 1MB 以下になります):
上記のように ImageIO と java.awt のアフィン変換を使って画像サイズに変換をかけて実装しています。
そんな場合に「画像を小さくしてから処理する」方法が考えられますが、Java によるその一例を紹介します。画像ファイルデータが img 変数にバイト配列で格納できているという前提で、横幅を 800 ピクセル、縦横比を変えずに高さをそれにあわせる形で変更するような処理内容を記述しています(こうすると、大抵 1MB 以下になります):
byte[] img = null; //. この変数に画像データが byte 配列で格納されているものとする
:
:
//. 画像のサイズを変更
if( img != null ){
BufferedImage src = null;
BufferedImage dst = null;
AffineTransformOp xform = null;
InputStream is = new ByteArrayInputStream( img );
src = ImageIO.read( is );
int width = src.getWidth(); //. オリジナル画像の幅
int height = src.getHeight(); //. オリジナル画像の高さ
int w = 800; //. 幅をこの数値に合わせて調整する
int new_height = w * height / width;
int new_width = w;
//. 画像変換
xform = new AffineTransformOp( AffineTransform.getScaleInstance( ( double )new_width / width, ( double )new_height / height ), AffineTransformOp.TYPE_BILINEAR );
dst = new BufferedImage( new_width, new_height, src.getType() );
xform.filter( src, dst );
//. 変換後のバイナリイメージを byte 配列に再格納
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write( dst, "jpeg", baos );
img = baos.toByteArray();
}
上記のように ImageIO と java.awt のアフィン変換を使って画像サイズに変換をかけて実装しています。
