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 java.awt.geom.AffineTransform; 019import java.awt.image.AffineTransformOp; 020import java.awt.image.BufferedImage; 021 022import org.opengion.fukurou.system.OgRuntimeException ; // 6.4.2.0 (2016/01/29) 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 * Usage: java org.opengion.fukurou.util.ImageResizer [Input Filename] [OutputFilename] [-max=maxResize] [-ratio=ratio] [-x=sizeX] [-y=sizeY] 172 * 173 * @og.rev 6.4.5.1 (2016/04/28) mainメソッドの起動方法を変更します。 174 * 175 * [-max=MaxResize] :最大サイズを指定して、リサイズします。 176 * [-ratio=ratio] :縮小率を指定して、リサイズします。 177 * [-x=sizeX] [-y=sizeY] : X,Y サイズを指定して、リサイズします。 178 * 179 * @param args 引数文字列配列 入力ファイル、出力ファイル、縦横最大サイズ 180 */ 181 public static void main( final String[] args ) { 182 if( args.length < 3 ) { 183 LogWriter.log( "Usage: java org.opengion.fukurou.util.ImageResizer [Input Filename] [OutputFilename] [-max=maxResize] [-ratio=ratio] [-x=sizeX] [-y=sizeY]" ); 184 return ; 185 } 186 187 final String inFile = args[0]; 188 final String outFile = args[1]; 189 190 int maxResize = -1; 191 double ratio = -1d; 192 int sizeX = -1; 193 int sizeY = -1; 194 195 for( int i=2; i<args.length; i++ ) { 196 if( args[i].startsWith( "-max=" ) ) { maxResize = Integer.parseInt( args[i].substring( 5 ) ); } // 5 = "-max=".length() 197 if( args[i].startsWith( "-ratio=" ) ) { ratio = Double.parseDouble( args[i].substring( 7 ) ); } // 7 = "-ratio=".length() 198 if( args[i].startsWith( "-x=" ) ) { sizeX = Integer.parseInt( args[i].substring( 3 ) ); } // 3 = "-x=".length() 199 if( args[i].startsWith( "-y=" ) ) { sizeY = Integer.parseInt( args[i].substring( 3 ) ); } // 3 = "-y=".length() 200 } 201 202 final ImageResizer ir = new ImageResizer( inFile ); 203 204 if( maxResize > 0 ) { 205 ir.resizeByPixel( outFile, maxResize ); 206 } 207 if( ratio > 0d ) { 208 ir.resizeByRatio( outFile, ratio ); 209 } 210 if( sizeX > 0 && sizeY > 0 ) { 211 ir.resizeByPixel( outFile, sizeX , sizeY ); 212 } 213 } 214}