001package com.hfg.image; 002 003 004 005import java.awt.Dimension; 006import java.awt.Image; 007import java.awt.image.BufferedImage; 008import java.io.File; 009import java.io.FileInputStream; 010import java.io.FileOutputStream; 011import java.io.IOException; 012import java.io.InputStream; 013import java.io.OutputStream; 014import java.util.Iterator; 015import java.util.Locale; 016import javax.imageio.IIOImage; 017import javax.imageio.ImageIO; 018import javax.imageio.ImageTypeSpecifier; 019import javax.imageio.ImageWriteParam; 020import javax.imageio.ImageWriter; 021import javax.imageio.metadata.IIOMetadata; 022import javax.imageio.plugins.jpeg.JPEGImageWriteParam; 023import javax.imageio.stream.FileImageOutputStream; 024import javax.imageio.stream.ImageOutputStream; 025 026import com.hfg.util.StringUtil; 027 028 029//------------------------------------------------------------------------------ 030/** 031 * General Image IO functions using ImageIO. 032 * 033 * @author J. Alex Taylor, hairyfatguy.com 034 */ 035//------------------------------------------------------------------------------ 036// com.hfg XML/HTML Coding Library 037// 038// This library is free software; you can redistribute it and/or 039// modify it under the terms of the GNU Lesser General Public 040// License as published by the Free Software Foundation; either 041// version 2.1 of the License, or (at your option) any later version. 042// 043// This library is distributed in the hope that it will be useful, 044// but WITHOUT ANY WARRANTY; without even the implied warranty of 045// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 046// Lesser General Public License for more details. 047// 048// You should have received a copy of the GNU Lesser General Public 049// License along with this library; if not, write to the Free Software 050// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 051// 052// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com 053// [email protected] 054//------------------------------------------------------------------------------ 055 056public class ImageIO_Util 057{ 058 public static float DEFAULT_JPG_QUALITY = 0.85f; 059 060 static 061 { 062 ImageIO.scanForPlugins(); 063 } 064 065 //-------------------------------------------------------------------------- 066 public static void writeBufferedImageAsJpeg(BufferedImage inImage, OutputStream inStream) 067 throws IOException 068 { 069 writeBufferedImageAsJpeg(inImage, inStream, DEFAULT_JPG_QUALITY); 070 } 071 072 //-------------------------------------------------------------------------- 073 public static void writeBufferedImageAsJpeg(BufferedImage inBufferedImage, OutputStream inStream, float inJpgQuality) 074 throws IOException 075 { 076 ImageWriter jpegWriter = ImageIO.getImageWritersByFormatName("JPEG").next(); 077 078 ImageWriteParam params = jpegWriter.getDefaultWriteParam(); 079 params.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); 080 params.setCompressionQuality(inJpgQuality); 081 082 ImageOutputStream out = ImageIO.createImageOutputStream(inStream); 083 jpegWriter.setOutput(out); 084 jpegWriter.write(null, new IIOImage(inBufferedImage,null,null),params); 085 jpegWriter.dispose(); 086 } 087 088 //--------------------------------------------------------------------------- 089 public static Dimension getDimension(File inImgFile) 090 { 091 Dimension dimension; 092 try 093 { 094 BufferedImage image = ImageIO.read(inImgFile); 095 dimension = new Dimension(image.getWidth(), image.getHeight()); 096 } 097 catch (IOException e) 098 { 099 throw new RuntimeException(e); 100 } 101 102 return dimension; 103 } 104 105 //--------------------------------------------------------------------------- 106 public static Dimension getDimension(InputStream inImgStream) 107 { 108 Dimension dimension; 109 try 110 { 111 BufferedImage image = ImageIO.read(inImgStream); 112 dimension = new Dimension(image.getWidth(), image.getHeight()); 113 } 114 catch (IOException e) 115 { 116 throw new RuntimeException(e); 117 } 118 119 return dimension; 120 } 121 122 //-------------------------------------------------------------------------- 123 public static void convertImage(File inOrigImg, File inDestImg, float inCompressionQuality) 124 { 125 ImageFormat destFormat = ImageFormat.guessFormatFromName(inDestImg.getName()); 126 127 try 128 { 129 // Read input image from file 130 BufferedImage srcImage = readImageFile(inOrigImg); 131 132 if (destFormat == ImageFormat.JPEG) 133 { 134 Iterator<ImageWriter> writerIter = ImageIO.getImageWritersBySuffix(destFormat.getFileExtension()); 135 ImageWriteParam param = new JPEGImageWriteParam(Locale.getDefault()); 136 param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); 137 param.setCompressionQuality(inCompressionQuality); 138 ImageWriter writer =writerIter.next(); 139 IIOMetadata metadata = writer.getDefaultImageMetadata(new ImageTypeSpecifier(srcImage), param); 140 ImageOutputStream outputStream = new FileImageOutputStream(inDestImg); 141 writer.setOutput(outputStream); 142 writer.write(metadata, new IIOImage(srcImage, null, metadata), param); 143 writer.dispose(); 144 outputStream.close(); 145 } 146 else 147 { 148 FileOutputStream outputStream = null; 149 try 150 { 151 outputStream = new FileOutputStream(inDestImg); 152 // Format to be converted to can be one of: jpeg, png, bmp, wbmp, and gif 153 ImageIO.write(srcImage, destFormat.getFileExtension(), outputStream); 154 } 155 finally 156 { 157 if (outputStream != null) outputStream.close(); 158 } 159 } 160 } 161 catch (IOException e) 162 { 163 throw new RuntimeException(e); 164 } 165 } 166 /* 167 BufferedImage sourceImage = ImageIO.read(inputStream); 168 Image thumbnail = sourceImage.getScaledInstance(width, -1, Image.SCALE_SMOOTH); 169 BufferedImage bufferedThumbnail = new BufferedImage(thumbnail.getWidth(null), 170 thumbnail.getHeight(null), 171 BufferedImage.TYPE_INT_RGB); 172 bufferedThumbnail.getGraphics().drawImage(thumbnail, 0, 0, null); 173 ImageIO.write(bufferedThumbnail, "jpeg", outputStream); 174 */ 175 176 177 //-------------------------------------------------------------------------- 178 179 /** 180 If the destination format is JPG, a default compression quality of 0.7 is used. 181 */ 182 public static void scaleDownImage(File inImgFile, int inMaxDimension, File inDestFile) 183 { 184 scaleDownImage(inImgFile, inMaxDimension, inDestFile, 0.7f); 185 } 186 187 //--------------------------------------------------------------------------- 188 public static void scaleDownImage(File inOrigImgFile, int inMaxDimension, File inDestImgFile, float inCompressionQuality) 189 { 190 if (null == inOrigImgFile) 191 { 192 throw new RuntimeException("No source image was specified!"); 193 } 194 195 ImageFormat destFormat = ImageFormat.guessFormatFromName(inDestImgFile.getName()); 196 197 try 198 { 199 // Read input image from file 200 BufferedImage sourceImage = readImageFile(inOrigImgFile); 201 202 int width = -1; 203 int height = -1; 204 if (sourceImage.getWidth() > sourceImage.getHeight()) 205 { 206 width = inMaxDimension; 207 } 208 else 209 { 210 height = inMaxDimension; 211 } 212 213 Image resizedImage = sourceImage.getScaledInstance(width, height, Image.SCALE_SMOOTH); 214 // Allocate a new BufferedImage 215 BufferedImage bufferedResizedImage = new BufferedImage(resizedImage.getWidth(null), 216 resizedImage.getHeight(null), 217 BufferedImage.TYPE_INT_RGB); 218 // Draw the resized image onto the new BufferedImage 219 bufferedResizedImage.getGraphics().drawImage(resizedImage, 0, 0, null); 220 221 if (destFormat == ImageFormat.JPEG) 222 { 223 Iterator<ImageWriter> writerIter = ImageIO.getImageWritersBySuffix(destFormat.getFileExtension()); 224 ImageWriteParam param = new JPEGImageWriteParam(Locale.getDefault()); 225 param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); 226 param.setCompressionQuality(inCompressionQuality); 227 ImageWriter writer =writerIter.next(); 228 IIOMetadata metadata = writer.getDefaultImageMetadata(new ImageTypeSpecifier(bufferedResizedImage), param); 229 ImageOutputStream outputStream = new FileImageOutputStream(inDestImgFile); 230 writer.setOutput(outputStream); 231 writer.write(metadata, new IIOImage(bufferedResizedImage, null, metadata), param); 232 writer.dispose(); 233 outputStream.close(); 234 } 235 else 236 { 237 FileOutputStream outputStream = null; 238 try 239 { 240 outputStream = new FileOutputStream(inDestImgFile); 241 // Format to be converted to can be one of: jpeg, png, bmp, wbmp, and gif 242 if (! ImageIO.write(bufferedResizedImage, destFormat.getFileExtension(), outputStream)) 243 { 244 String msg = "The destination image " + StringUtil.singleQuote(inDestImgFile) + " couldn't be written!"; 245 if (destFormat.equals(ImageFormat.TIFF)) 246 { 247 msg += " The jai-imageio-core jar is needed to read/write TIFF format."; 248 } 249 250 throw new RuntimeException(msg); 251 } 252 } 253 finally 254 { 255 if (outputStream != null) outputStream.close(); 256 } 257 } 258 } 259 catch (IOException e) 260 { 261 throw new RuntimeException(e); 262 } 263 } 264 265 266 //-------------------------------------------------------------------------- 267 private static BufferedImage readImageFile(File inSrcImg) 268 throws IOException 269 { 270 BufferedImage srcImage = null; 271 272 ImageFormat srcFormat = ImageFormat.guessFormatFromName(inSrcImg.getName()); 273 274 FileInputStream inputStream = null; 275 try 276 { 277 inputStream = new FileInputStream(inSrcImg); 278 279 // Read input image from file 280 srcImage = ImageIO.read(inputStream); 281 if (null == srcImage) 282 { 283 String msg = "The input image " + StringUtil.singleQuote(inSrcImg) + " couldn't be read!"; 284 if (srcFormat != null 285 && srcFormat.equals(ImageFormat.TIFF)) 286 { 287 msg += " The jai-imageio-core jar is needed to read/write TIFF format."; 288 } 289 290 throw new RuntimeException(msg); 291 } 292 } 293 finally 294 { 295 if (inputStream != null) inputStream.close(); 296 } 297 298 return srcImage; 299 } 300 301}