    001/*
    002 * Copyright (c) 2009 The openGion Project.
    003 *
    004 * Licensed under the Apache License, Version 2.0 (the "License");
    005 * you may not use this file except in compliance with the License.
    006 * You may obtain a copy of the License at
    007 *
    008 *     http://www.apache.org/licenses/LICENSE-2.0
    009 *
    010 * Unless required by applicable law or agreed to in writing, software
    011 * distributed under the License is distributed on an "AS IS" BASIS,
    012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
    013 * either express or implied. See the License for the specific language
    014 * governing permissions and limitations under the License.
    015 */
    016package org.opengion.fukurou.util;
    017
    018import org.opengion.fukurou.system.OgRuntimeException ;         // 6.4.2.0 (2016/01/29)
    019import java.awt.geom.AffineTransform;
    020import java.awt.image.AffineTransformOp;
    021import java.awt.image.BufferedImage;
    022
    023import org.opengion.fukurou.system.LogWriter;                                           // 6.4.2.0 (2016/01/29) package変更 fukurou.util → fukurou.system
    024
    025/**
    026 * ImageResizer は、画像ファイルのリサイズを行うためのクラスです。
    027 * ここでの使い方は、初期化時に、オリジナルの画像ファイルを指定し、
    028 * 変換時に各縮小方法に対応したメソッドを呼び出し、画像を変換します。
    029 * 変換方法としては、以下の3つがあります。
    030 * ①最大サイズ(px)指定による変換
    031 *   縦横の最大サイズ(px)を指定し、変換を行います。
    032 *   横長の画像については、変換後の横幅=最大サイズとなり、縦幅については、横幅の
    033 *   縮小率に従って決定されます。
    034 *   逆に縦長の画像については、変換後の縦幅=最大サイズとなり、横幅については、縦幅の
    035 *   縮小率に従って決定されます。
    036 * ②縦横サイズ(px)指定による変換
    037 *   縦横の変換後のサイズ(px)を個別に指定し、変換を行います。
    038 * ③縮小率指定による変換
    039 *   "1"を元サイズとする縮小率を指定し、変換を行います。
    040 *   縮小率は、縦横で同じ縮小率が適用されます。
    041 * 入力フォーマットとしてはJPEG/PNG/GIFに、出力フォーマットとしてはJPEG/PNGに対応しています。
    042 * 出力フォーマットについては、出力ファイル名の拡張子より自動的に決定されますが、一般的には
    043 * サイズが小さくなるjpegファイルを推奨します。
    044 * 入出力フォーマットについて、対応していないフォーマットが指定された場合は例外が発生します。
    045 * また、縦横の出力サイズが入力サイズの縦横よりも両方大きい場合、変換は行われず、入力ファイルが
    046 * そのままコピーされて出力されます。(拡大変換は行われません)
    047 *
    048 * @og.rev 6.0.2.3 (2014/10/10) static 系のメソッドは、ImageUtil に移動
    049 *
    050 * @version  4.0
    051 * @author   Hiroki Nakamura
    052 * @since    JDK5.0,
    053 */
    054public class ImageResizer {
    055
    056        private final BufferedImage inputImage; // 入力画像オブジェクト
    057
    058        private final int inSizeX;                              // 入力画像の横サイズ
    059        private final int inSizeY;                              // 入力画像の縦サイズ
    060
    061        /**
    062         * 入力ファイル名を指定し、画像縮小オブジェクトを初期化します。
    063         *
    064         * @og.rev 5.4.3.5 (2012/01/17) CMYK対応
    065         * @og.rev 5.4.3.7 (2012/01/20) FAIでのファイル取得方法変更
    066         * @og.rev 5.4.3.8 (2012/01/24) エラーメッセージ追加
    067         * @og.rev 5.6.5.3 (2013/06/28) 入力画像の形式 を ImageIO から取り出します。
    068         * @og.rev 5.6.5.3 (2013/06/28) 入力画像の形式 を ImageIO から取り出します。
    069         * @og.rev 6.0.2.3 (2014/10/10) ImageUtil から取り出します。
    070         *
    071         * @param fin 入力ファイル名
    072         */
    073        public ImageResizer( final String fin ) {
    074                inputImage = ImageUtil.readFile( fin );
    075
    076                inSizeX = inputImage.getWidth();
    077                inSizeY = inputImage.getHeight();
    078        }
    079
    080        /**
    081         * 縦横の最大サイズ(px)を指定し、変換を行います。
    082         * 横長の画像については、変換後の横幅=最大サイズとなり、縦幅については、横幅の
    083         * 縮小率に従って決定されます。
    084         * 逆に縦長の画像については、変換後の縦幅=最大サイズとなり、横幅については、縦幅の
    085         * 縮小率に従って決定されます。
    086         *
    087         * @param fname 出力ファイル名
    088         * @param maxSize 変換後の縦横の最大サイズ
    089         */
    090        public void resizeByPixel( final String fname, final int maxSize ) {
    091                int sizeX = 0;
    092                int sizeY = 0;
    093                if( inSizeX > inSizeY ) {
    094                        sizeX = maxSize;
    095                        sizeY = inSizeY * maxSize / inSizeX;
    096                }
    097                else {
    098                        sizeX = inSizeX * maxSize / inSizeY;
    099                        sizeY = maxSize;
    100                }
    101                convert( inputImage, fname, sizeX, sizeY );
    102        }
    103
    104        /**
    105         * 縦横の変換後のサイズ(px)を個別に指定し、変換を行います。
    106         *
    107         * @param fname 出力ファイル名
    108         * @param sizeX 変換後の横サイズ(px)
    109         * @param sizeY 変換後の縦サイズ(px)
    110         */
    111        public void resizeByPixel( final String fname, final int sizeX, final int sizeY ) {
    112                convert( inputImage, fname, sizeX, sizeY );
    113        }
    114
    115        /**
    116         * "1"を元サイズとする縮小率を指定し、変換を行います。
    117         *  縮小率は、縦横で同じ縮小率が適用されます。
    118         *
    119         * @param fname 出力ファイル名
    120         * @param ratio 縮小率
    121         */
    122        public void resizeByRatio( final String fname, final double ratio ) {
    123                final int sizeX = (int)( inSizeX * ratio );
    124                final int sizeY = (int)( inSizeY * ratio );
    125                convert( inputImage, fname, sizeX, sizeY );
    126        }
    127
    128        /**
    129         * 画像の変換を行うための内部共通メソッドです。
    130         *
    131         * @og.rev 5.4.1.0 (2011/11/01) 画像によってgetTypeが0を返し、エラーになる不具合を修正
    132         * @og.rev 5.6.5.3 (2013/06/28) 出力画像の形式 を ImageIO から取り出します。
    133         * @og.rev 5.6.5.3 (2013/06/28) 5.6.6.1 (2013/07/12) getSuffix するタイミングを後ろにする。
    134         * @og.rev 5.6.6.1 (2013/07/12) 拡張子の変更があるので、変換しない処理は、ない。
    135         * @og.rev 6.0.2.3 (2014/10/10) ImageUtil のメソッドを一部使用するように変更します。
    136         *
    137         * @param inputImage 入力画像オブジェクト
    138         * @param fname 出力ファイル名
    139         * @param sizeX 横サイズ(px)
    140         * @param sizeY 縦サイズ(px)
    141         */
    142        private void convert( final BufferedImage inputImage, final String fname, final int sizeX, final int sizeY ) {
    143                // 5.6.6.1 (2013/07/12) getSuffix するタイミングを後ろにする。
    144                // 5.6.5.3 (2013/06/28) 出力画像の形式 を ImageIO から取り出します。
    145                // 6.0.2.3 (2014/10/10) ImageUtil のメソッド
    146                if( !ImageUtil.isWriterSuffix( fname ) ) {
    147                        final String errMsg = "出力ファイルは" + ImageUtil.WRITER_SUFFIXES + "のいずれかの形式のみ指定可能です。" + "File=[" + fname + "]";
    148                        throw new OgRuntimeException( errMsg );
    149                }
    150
    151                // 5.4.1.0 (2011/11/01) 画像によってgetTypeが0を返し、エラーになる不具合を修正
    152                final int type = inputImage.getType();
    153                BufferedImage resizeImage = null;
    154                if( type == 0 ) {
    155                        resizeImage = new BufferedImage( sizeX, sizeY, BufferedImage.TYPE_4BYTE_ABGR_PRE );
    156                }
    157                else {
    158                        resizeImage = new BufferedImage( sizeX, sizeY, inputImage.getType() );
    159                }
    160                AffineTransformOp ato = null;
    161                ato = new AffineTransformOp(
    162                                AffineTransform.getScaleInstance(
    163                                                (double)sizeX/inSizeX, (double)sizeY/inSizeY ), null );
    164                ato.filter( inputImage, resizeImage );
    165
    166                ImageUtil.saveFile( resizeImage,fname );                // 6.0.2.3 (2014/10/10) ImageUtil のメソッド
    167
    168        }
    169
    170        /**
    171         * メイン処理です。
    172         * Usage: java org.opengion.fukurou.util.ImageResizer [Input Filename] [OutputFilename] [-max=maxResize] [-ratio=ratio] [-x=sizeX] [-y=sizeY]
    173         *
    174         * @og.rev 6.4.5.1 (2016/04/28) mainメソッドの起動方法を変更します。
    175         *
    176         *  [-max=MaxResize] :最大サイズを指定して、リサイズします。
    177         *  [-ratio=ratio]   :縮小率を指定して、リサイズします。
    178         *  [-x=sizeX] [-y=sizeY] : X,Y サイズを指定して、リサイズします。
    179         *
    180         * @param  args  引数文字列配列 入力ファイル、出力ファイル、縦横最大サイズ
    181         */
    182        public static void main( final String[] args ) {
    183                if( args.length < 3 ) {
    184                        LogWriter.log( "Usage: java org.opengion.fukurou.util.ImageResizer [Input Filename] [OutputFilename] [-max=maxResize] [-ratio=ratio] [-x=sizeX] [-y=sizeY]" );
    185                        return ;
    186                }
    187
    188                final String inFile  = args[0];
    189                final String outFile = args[1];
    190
    191                int             maxResize       = -1;
    192                double  ratio           = -1d;
    193                int             sizeX           = -1;
    194                int             sizeY           = -1;
    195
    196                for( int i=2; i<args.length; i++ ) {
    197                        if( args[i].startsWith( "-max="   ) ) { maxResize       = Integer.parseInt(             args[i].substring( 5 ) ); }             // 5 = "-max=".length()
    198                        if( args[i].startsWith( "-ratio=" ) ) { ratio           = Double.parseDouble(   args[i].substring( 7 ) ); }             // 7 = "-ratio=".length()
    199                        if( args[i].startsWith( "-x="     ) ) { sizeX           = Integer.parseInt(             args[i].substring( 3 ) ); }             // 3 = "-x=".length()
    200                        if( args[i].startsWith( "-y="     ) ) { sizeY           = Integer.parseInt(             args[i].substring( 3 ) ); }             // 3 = "-y=".length()
    201                }
    202
    203                final ImageResizer ir = new ImageResizer( inFile );
    204
    205                if( maxResize > 0 ) {
    206                        ir.resizeByPixel( outFile, maxResize );
    207                }
    208                if( ratio > 0d ) {
    209                        ir.resizeByRatio( outFile, ratio );
    210                }
    211                if( sizeX > 0 && sizeY > 0 ) {
    212                        ir.resizeByPixel( outFile, sizeX , sizeY );
    213                }
    214        }
    215}