2011-03-28 205 views
3

我想爲一組圖像創建縮略圖。爲此,我使用下面的代碼。在Java中創建縮略圖

public void run() { 
     try{ 
    BufferedImage originalImage = ImageIO.read(new File(url)); 
    int type = originalImage.getType() == 0? BufferedImage.TYPE_INT_ARGB : originalImage.getType(); 
      IMG_HEIGHT = (originalImage.getHeight()*600)/originalImage.getWidth(); 
    BufferedImage resizeImageJpg = resizeImage(originalImage, type); 
    ImageIO.write(resizeImageJpg, "jpg", new File(thumb)); 
      originalImage.flush(); 
      resizeImageJpg.flush(); 
      System.gc(); 

}catch(IOException e){ 
    System.out.println(e.getMessage()); 
      System.out.println("Not Created:"+url); 
} 
    } 
private static BufferedImage resizeImage(BufferedImage originalImage, int type){ 
BufferedImage resizedImage = new BufferedImage(IMG_WIDTH, IMG_HEIGHT, type); 
Graphics2D g = resizedImage.createGraphics(); 
g.drawImage(originalImage, 0, 0, IMG_WIDTH, IMG_HEIGHT, null); 
g.dispose(); 
    System.gc(); 
return resizedImage; 
} 

此代碼工作正常,並創建縮略圖。但問題是,在大量圖像的情況下,我得到「Java堆空間錯誤」。它是這個代碼的問題?我該如何解決這個問題。提前致謝。 如果您有其他任何調整大小的代碼,請給我。

+0

看來你已經完成堆空間。用你用來閱讀所有圖像的cicle完成代碼 – Heisenbug 2011-03-28 06:46:17

回答

3
+2

很高興它爲你工作;我寫這篇文章的全部原因是爲了很容易,很快地解決這個問題(OP):「我想要縮略圖,爲我做電腦!」圖書館有一些比這更先進的功能,但沒有更多。我已經確保它儘可能簡單/小巧,所以它不會丟失範圍,併成爲另一種通用的圖形API。 – 2011-04-27 15:43:09

0

你如何啓動這個過程?這段代碼似乎確實正在清理圖像。

唯一的選擇是通過添加-Xmx 512m(例如,將堆大小增加到512 MB)作爲VM命令行選項之一來增加堆大小。

+0

我也這麼做了。但這不是合適的解決方案。 – laradev 2011-03-28 07:18:57

+0

圖像的大小(和分辨率)是多少?如果圖像很大,那麼您必須確保有足夠的堆來同時加載3 - 4張圖像 – 2011-03-28 07:56:18

+0

輸入圖像是從filechooser獲得的。僅當我們選擇超過15張圖像時纔會出現堆空間錯誤。 我正在運行for循環從0到不。的選定圖像。在那個循環中,我調用上面提到的創建縮略圖的函數。 – laradev 2011-03-28 08:26:43

0

在Java中創建縮略圖需要相應的工具:ImageMagick

從Java調用它,並享受結果。它總是比Java提供的可用庫更好,更安全,更快速。

1

我沒有看到你在哪裏設置IMG_WIDTH,它是否會被留下巨大的價值。您應該更願意將目標寬度和高度作爲參數,您設置高度的方式可防止多線程使用,並且使其很難閱讀。我懷疑目標圖像的高度真的是對象狀態的一部分。

此外,您確定您正確設置圖像高度,高度與高度和寬度之間的比例有關,如果目標圖像的寬度是寬度,則窄圖像會給您非常高的圖像和拉伸圖像保持不變。

最後一件事,http://www.jhlabs.com/ip/filters/index.html有一些有用的圖像處理代碼(包括調整大小),我已經使用了很多次。

假設您的圖片很大,您可能需要查看JAI並使用嵌入的縮略圖或二次採樣來減少所需的內存。

public static BufferedImage getThumb(ImageReader reader, int size) throws IOException { 
    BufferedImage img; 

    try { 
     if (reader.getNumThumbnails(0) > 0) { 
      img = reader.readThumbnail(0, 0); 
     } else { 
      ImageReadParam param = reader.getDefaultReadParam(); 
      param.setSourceSubsampling(4, 4, 0, 0); 
      img = reader.read(0); //read(0, param); 
     } 
     throw new Exception(); 
    } catch (Throwable t) { 
     img = null; 
    } 

    return img != null ? resizeImage(img, size) : null; 
} 

public static BufferedImage getThumb(File file, double scale) throws IOException { 
    BufferedImage img = null; 

    try { 
     Class<?> c = ImageUtil.class.getClassLoader().loadClass("javax.media.jai.JAI"); 
     Class<?> ic = ImageUtil.class.getClassLoader().loadClass("javax.media.jai.Interpolation"); 
     Class<?> sc = ImageUtil.class.getClassLoader().loadClass("javax.media.jai.operator.ScaleDescriptor"); 
     Method jaiCreate = c.getMethod("create", String.class, Object.class); 
     Method getInstance = findMethod(ic, "getInstance"); 
     Method sdCreate = findMethod(sc, "create"); 

     if (c != null) { 
      Object image = jaiCreate.invoke(null, "fileload", file.getAbsolutePath());    
      Object[] params = { image, (float) scale, (float) scale, 
        0.0f, 0.0f, getInstance.invoke(null, 2), null }; 
      Object sd = sdCreate.invoke(null, params); 
      Method m = sd.getClass().getMethod("getAsBufferedImage"); 
      img = (BufferedImage) m.invoke(sd); 
     } 
    } catch (Throwable tt) { 
     System.out.println("Could not read image using JAI, maybe JAI is not installed."); 
     System.out.println(tt); 
    } 

    return img; 
} 
+0

我將IMG_WIDTH靜態設置爲600以外的功能。 – laradev 2011-03-28 07:29:08

+0

你輸入圖像的尺寸是多少(尺寸方面),它們總是具有固定的高寬比?如果不是,你最終會得到一些拉伸的圖像。 – vickirk 2011-03-28 07:59:14

+0

我明白你的意思了。但主要問題是堆空間錯誤。 – laradev 2011-03-28 08:17:57