Flash
Flash

Reputation: 3021

Creating thumbnail views of images using Java

I have an application where i need to select a folder containing pictures and need to display a thumbnail view of those images using Java . I dont have any idea as to how to represent images in a thumbnail format .

Any resources like code examples , theory or links would be really helpful.

Thank You

Upvotes: 2

Views: 4964

Answers (2)

extraneon
extraneon

Reputation: 23950

The following code scales the entire image into an area. You can copy-paste the code and run it to see what it does.

The interesting call is g2d.drawImage(img, 0, 0, thumb.getWidth() - 1, thumb.getHeight() - 1, 0, 0, img.getWidth() - 1, img.getHeight() - 1, null); which copies the image into the thumbnail, scaling it to fit.

If you want different scalings to preserve the aspect ratio you could decide to use scale() on the g2d, or select a different source coordinates.

import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;

import javax.imageio.ImageIO;

public class ThumbnailFactory {

    public ThumbnailFactory() {
    }

    public void run(String folder) {
        File dir = new File(folder);
        for (File file : dir.listFiles()) {
            createThumbnail(file);
        }
    }

    private void createThumbnail(File file) {
        try {
            // BufferedImage is the best (Toolkit images are less flexible)
            BufferedImage img = ImageIO.read(file);
            BufferedImage thumb = createEmptyThumbnail();

            // BufferedImage has a Graphics2D
            Graphics2D g2d = (Graphics2D) thumb.getGraphics(); 
            g2d.drawImage(img, 0, 0, 
                          thumb.getWidth() - 1,
                          thumb.getHeight() - 1, 
                          0, 0, 
                          img.getWidth() - 1,
                          img.getHeight() - 1, 
                          null);
            g2d.dispose();
            ImageIO.write(thumb, "PNG", createOutputFile(file));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private File createOutputFile(File inputFile) {
        // You'll want something better than this...
        return new File(inputFile.getAbsolutePath() 
                        + ".thumb.png");
    }

    private BufferedImage createEmptyThumbnail() {
        return new BufferedImage(100, 200, 
                                 BufferedImage.TYPE_INT_RGB);
    }

    public static void main(String[] args) {
        ThumbnailFactory fac = new ThumbnailFactory();
        fac.run("c:\\images");
    }
}

Upvotes: 1

Mark Pope
Mark Pope

Reputation: 11264

I have this code that I use in one of my projects. I found on the net a while ago (not sure where but if anyone recognises it please let me know so I can reference it):

private static byte[] createThumbnail(byte[] bytes)
{
    try
    {
        double scale;
        int sizeDifference, originalImageLargestDim;
        Image inImage = ImageIO.read(new ByteArrayInputStream(bytes));

        //find biggest dimension        
        if(inImage.getWidth(null) > inImage.getHeight(null))
        {
            scale = (double)LARGEST_DIMENSION/(double)inImage.getWidth(null);
            sizeDifference = inImage.getWidth(null) - LARGEST_DIMENSION;
            originalImageLargestDim = inImage.getWidth(null);
        }
        else
        {
            scale = (double)LARGEST_DIMENSION/(double)inImage.getHeight(null);
            sizeDifference = inImage.getHeight(null) - LARGEST_DIMENSION;
            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;
            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 - LARGEST_DIMENSION;
                    }
                    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.
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(os);
        encoder.encode(outImage);
        return os.toByteArray();
    }
    catch(Exception e)
    {
        throw new RuntimeException(e);
    }
}

Upvotes: 1

Related Questions