使用Java创建图像的缩略图视图

时间:2011-05-01 11:16:56

标签: java image-manipulation

我有一个应用程序,我需要选择一个包含图片的文件夹,并需要使用Java显示这些图像的缩略图。我不知道如何用缩略图格式表示图像。

代码示例,理论或链接等任何资源都非常有用。

谢谢

2 个答案:

答案 0 :(得分:1)

我在我的一个项目中使用了这段代码。我刚才在网上找到了(不知道在哪里,但如果有人认出它请告诉我,以便我可以参考):

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);
    }
}

答案 1 :(得分:1)

以下代码将整个图像缩放为一个区域。您可以复制粘贴代码并运行它以查看它的作用。

有趣的调用是g2d.drawImage(img, 0, 0, thumb.getWidth() - 1, thumb.getHeight() - 1, 0, 0, img.getWidth() - 1, img.getHeight() - 1, null);,它将图像复制到缩略图中,缩放它以适应。

如果您想要不同的缩放比例来保留纵横比,您可以决定在g2d上使用scale(),或者选择不同的源坐标。

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");
    }
}