2017-02-05 55 views
-2

我需要使用Java生成給定大小(即10KB,100KB,1MB,10MB等)的圖像(圖像格式無關緊要)。圖像可以是填充背景顏色的任何形狀,對圖像內容沒有限制。Java - 如何生成給定大小的圖像?

編輯#1:其將要創建的圖像的大小是可變的,所以爲了在創建圖像是安全的從heap space例外,我期待內存使用長期的有效途徑

編輯#2:獲取java.lang.IllegalArgumentException: Dimensions (width=48000 height=48000) are too large例外,當我嘗試使用的Graphics2D庫,它是必要的,以便產生大的文件大小的圖像尺寸48000x48000生成圖像。

編輯#3:當尺寸越來越大,我體驗到即使我已手動配置,其將要執行的Java程序的-Xmx參數java.lang.OutOfMemoryError: Java heap space例外。

+0

可能的重複http://stackoverflow.com/questions/19281195/creating-images-with-a-java/19281350#19281350 – MadProgrammer

+0

我也有一個尺寸標準,這是問題的關鍵部分。 – talha06

+0

當然,我知道這些參數,但我需要創建各種大小的圖像。此外,我要求**創建圖像的最有效方法**,以防止任何可能的「堆大小」異常。 – talha06

回答

1

下面是一些非常簡單的示例代碼,應儘可能符合您的要求,只要我能理解。該程序應該可以非常有效地工作,幾乎不需要任何內存,但仍然可以創建大小高達(大約)2GB的圖像文件(如果您願意,還可以輕鬆調整它以創建更大的圖像)。

假設:

  • 的圖像格式並不重要,所以我們會選擇PGM format(二進制「P5」模式)
  • 的圖像可以是任何形狀/顏色,讓我們拭目以待只是做最簡單的事情,寫一條黑線。
  • 重要的大小是圖像文件的大小(下面的代碼不會寫入字節這個大小,但可以很容易地通過在寫入之前減去最小文件頭的大小來修改)。

輸入的文件大小,其次是文件名(要使用.pgm作爲擴展名)。舉個例子:

$ java -cp ... WritePGM 2147483640 foo.pnm 

以上將創建我的JVM允許讀回的最大可能映像,大約2 GB。

代碼:

public class WritePGM { 
    public static void main(String[] args) throws IOException { 

     int size = Integer.parseInt(args[0]); 
     File file = new File(args[1]); 

     try (OutputStream out = new BufferedOutputStream(new FileOutputStream(file))) { 
      // Format P5/binary gray 
      out.write("P5\n".getBytes(StandardCharsets.UTF_8)); 
      // Dimensions (width/height) 
      out.write(String.format("%s 1\n", size).getBytes(StandardCharsets.UTF_8)); 
      // MaxSample 
      out.write("255\n".getBytes(StandardCharsets.UTF_8)); 

      // Just write a single line of 0-bytes 
      for (int i = 0; i < size; i++) { 
       out.write(0); 
      } 
     } 
    } 
} 

PS:如果你需要一個ImageIO的插件,使用Java來讀取生成的文件,你可以使用JAI ImageIO的或my own PNM plugin,但你當然會遇到相同的內存問題就像你試圖用Java2D生成這樣的圖像一樣(BufferedImage)。


從理論上講,你也可以使用類似技術的格式,如JPEG或PNG創建文件,但這些格式更難實現。而且,它們被壓縮,所以預測文件大小很難。

也許你可以使用額外的非圖像數據填充最小的JPEG,如XMP等。 PNG允許在沒有壓縮的情況下編寫Deflate塊,這可能是一個選項。或者使用額外的塊來填充。

像BMP這樣的非壓縮格式會更簡單。您可以使用與上述相同的技術,只需編寫一個固定的最小BMP標頭,設置正確的寬度並像上述那樣寫入圖像數據即可。 BMP確實需要行填充,並且不支持灰色數據,所以您需要做一些額外的工作。但肯定是可行的。

+0

真的很有效的解決方案,按預期工作,感謝您的貢獻。生成諸如'jpg','png'等衆所周知的圖像格式怎麼樣? – talha06

+1

@ talha06在答案的底部添加了關於此的一節。 – haraldK

-1

一種方式 -

1)創建一個BufferedImage目標CT: -

BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY); 

2)填寫您的BufferedImage對象(在這裏我假設你有適當的輸入存儲在爲int的2-d陣列的圖像稱爲IMG): -

for (int y = 0; y < image.getHeight(); y++) 
    { 
     for (int x = 0; x < image.getWidth(); x++) 
     { 

      image.setRGB(x, y, img[y][x]<<16 | img[y][x] << 8 | img[y][x]); 
     } 

    } 

3)將BufferedImage對象寫入磁盤: -

ImageIO.write(image, "jpg", new FileOutputStream(new File("SomePath/Name-of-Image.jpg"))); 
+0

除了尺寸標準外,所有的問題都是關鍵部分。 – talha06

+0

你想要做什麼?你正在閱讀一張圖片,做一些處理,然後寫回來?或者是別的什麼? – opensam

+0

需要爲學術研究生成各種尺寸的不同圖像(即10KB,100KB,1MB,10MB等)。 – talha06