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}