2011-05-01 81 views
2

我有一個應用程序,我需要選擇一個包含圖片的文件夾並需要使用Java顯示這些圖像的縮略圖視圖。我對如何以縮略圖格式表示圖像沒有任何想法。使用Java創建圖像的縮略圖

任何資源(如代碼示例,理論或鏈接)都會非常有用。

謝謝

+0

您想如何縮放縮略圖?一些圖像可能比高寬更寬;它們應該在x方向與y方向一樣縮放嗎? – extraneon 2011-05-01 12:31:00

回答

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

以下代碼縮放整個圖像到一個區域。您可以複製粘貼代碼並運行它以查看它的功能。

有趣的電話是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"); 
    } 
}