Mega Code Archive

 
Categories / Java / 2D Graphics GUI
 

Reads an image in a file and creates a thumbnail in another file

//package net.gqu.utils; import java.awt.Color; import java.awt.Graphics2D; import java.awt.Image; import java.awt.RenderingHints; import java.awt.Toolkit; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.io.FileOutputStream; import java.io.OutputStream; import javax.swing.ImageIcon; import com.sun.image.codec.jpeg.JPEGCodec; import com.sun.image.codec.jpeg.JPEGImageEncoder; public class Thumbnail {   /**   * Reads an image in a file and creates a thumbnail in another file.   * largestDimension is the largest dimension of the thumbnail, the other dimension is scaled accordingly.   * Utilises weighted stepping method to gradually reduce the image size for better results,   * i.e. larger steps to start with then smaller steps to finish with.   * Note: always writes a JPEG because GIF is protected or something - so always make your outFilename end in 'jpg'.   * PNG's with transparency are given white backgrounds   */   public String createThumbnail(String inFilename, String outFilename, int largestDimension)   {     try     {       double scale;       int sizeDifference, originalImageLargestDim;       if(!inFilename.endsWith(".jpg") && !inFilename.endsWith(".jpeg") && !inFilename.endsWith(".gif") && !inFilename.endsWith(".png"))       {         return "Error: Unsupported image type, please only either JPG, GIF or PNG";       }       else       {         Image inImage = Toolkit.getDefaultToolkit().getImage(inFilename);         if(inImage.getWidth(null) == -1 || inImage.getHeight(null) == -1)         {           return "Error loading file: \"" + inFilename + "\"";         }         else         {           //find biggest dimension                 if(inImage.getWidth(null) > inImage.getHeight(null))           {             scale = (double)largestDimension/(double)inImage.getWidth(null);             sizeDifference = inImage.getWidth(null) - largestDimension;             originalImageLargestDim = inImage.getWidth(null);           }           else           {             scale = (double)largestDimension/(double)inImage.getHeight(null);             sizeDifference = inImage.getHeight(null) - largestDimension;             originalImageLargestDim = inImage.getHeight(null);           }           //create an image buffer to draw to           BufferedImage outImage = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB); //arbitrary init so code compiles           Graphics2D g2d;           AffineTransform tx;           if(scale < 1.0d) //only scale if desired size is smaller than original           {             int numSteps = sizeDifference / 100;             int stepSize = sizeDifference / numSteps;             int stepWeight = stepSize/2;             int heavierStepSize = stepSize + stepWeight;             int lighterStepSize = stepSize - stepWeight;             int currentStepSize, centerStep;             double scaledW = inImage.getWidth(null);             double scaledH = inImage.getHeight(null);             if(numSteps % 2 == 1) //if there's an odd number of steps               centerStep = (int)Math.ceil((double)numSteps / 2d); //find the center step             else               centerStep = -1; //set it to -1 so it's ignored later             Integer intermediateSize = originalImageLargestDim, previousIntermediateSize = originalImageLargestDim;             Integer calculatedDim;             for(Integer i=0; i<numSteps; i++)             {               if(i+1 != centerStep) //if this isn't the center step               {                 if(i == numSteps-1) //if this is the last step                 {                   //fix the stepsize to account for decimal place errors previously                   currentStepSize = previousIntermediateSize - largestDimension;                 }                 else                 {                   if(numSteps - i > numSteps/2) //if we're in the first half of the reductions                     currentStepSize = heavierStepSize;                   else                     currentStepSize = lighterStepSize;                 }               }               else //center step, use natural step size               {                                         currentStepSize = stepSize;               }               intermediateSize = previousIntermediateSize - currentStepSize;               scale = (double)intermediateSize/(double)previousIntermediateSize;               scaledW = (int)scaledW*scale;               scaledH = (int)scaledH*scale;               outImage = new BufferedImage((int)scaledW, (int)scaledH, BufferedImage.TYPE_INT_RGB);               g2d = outImage.createGraphics();               g2d.setBackground(Color.WHITE);               g2d.clearRect(0, 0, outImage.getWidth(), outImage.getHeight());               g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);               tx = new AffineTransform();               tx.scale(scale, scale);               g2d.drawImage(inImage, tx, null);               g2d.dispose();               inImage = new ImageIcon(outImage).getImage();               previousIntermediateSize = intermediateSize;             }                           }           else           {           //just copy the original           outImage = new BufferedImage(inImage.getWidth(null), inImage.getHeight(null), BufferedImage.TYPE_INT_RGB);           g2d = outImage.createGraphics();           g2d.setBackground(Color.WHITE);           g2d.clearRect(0, 0, outImage.getWidth(), outImage.getHeight());           tx = new AffineTransform();           tx.setToIdentity(); //use identity matrix so image is copied exactly           g2d.drawImage(inImage, tx, null);           g2d.dispose();           }           //JPEG-encode the image and write to file.           OutputStream os = new FileOutputStream(outFilename);           JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(os);           encoder.encode(outImage);           os.close();         }       }     }     catch(Exception ex)     {       String errorMsg = "";       errorMsg += "<br>Exception: " + ex.toString();       errorMsg += "<br>Cause = " + ex.getCause();       errorMsg += "<br>Stack Trace = ";       StackTraceElement stackTrace[] = ex.getStackTrace();       for(int traceLine=0; traceLine<stackTrace.length; traceLine++)       {         errorMsg += "<br>" + stackTrace[traceLine];       }       return errorMsg;     }     return ""; //success   } }