2013-10-19 32 views
1

我正試圖編寫一個應用程序生成並保存Julia sets的高分辨率圖像,但我遇到了問題。我的代碼是創建一個大小几乎與我認爲應該是什麼相對應的文件,但是當我嘗試打開它時,有一個關於文件過早結束的錯誤消息。Java:使用FileOutputStream保存大的.bmp文件

我基本上採取一個大小*大小的正方形,然後對於這個正方形的每個像素,我正在計算複平面中的相應數字(從-1.5 - 1.5i到1.5 + 1.5i的片段),以及之後,我開始一個算法,確定它是否屬於某個Julia集合(我完全確定它能正常工作,所以你不必擔心它)。

我想生成非常高的分辨率(像20k * 20k像素,至少)圖像,所以我想用某種輸出流來做。我已經用BufferedImage,ImageIO.write()和類似的東西生成了這樣的圖像,但這些圖像不能處理接近9k * 9k像素的圖像(JVM堆大小問題)。我只是補充一下,這是我第一次嘗試像這樣創建一個文件,逐字節。

這裏是我的代碼:

import java.io.FileOutputStream; 
import java.io.IOException; 

public class Save_big_bmp{ 
    public static void main(String[] args) throws IOException{ 
     int size, filesize; 
     byte[] pixelColorBGR = new byte[3]; 
     boolean prisoner; 

     size=1000; 
     filesize=(3*size*size)+54; 
     Complex c = new Complex(-0.1, 0.65); 

     byte[] header= 
     {66, 77, (byte)((filesize >> 24) & 0xFF), (byte)((filesize >> 16) & 0xFF), 
     (byte)((filesize >> 8) & 0xFF), (byte)(filesize & 0xFF), 0, 0, 0, 0, 0, 0, 0, 54,  
     0, 0, 0, 40, (byte)((size >> 24) & 0xFF), (byte)((size >> 16) & 0xFF), 
     (byte)((size >> 8) & 0xFF), (byte)(size & 0xFF), (byte)((size >> 24) & 0xFF),  
     (byte)((size >> 16) & 0xFF), (byte)((size >> 8) & 0xFF), (byte)(size & 0xFF), 0, 1, 0, 24, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 

     FileOutputStream output = new FileOutputStream("output.bmp"); 
     output.write(header); 

     for(int i=0;i<size;i++){ 
      for(int j=size;j>=0;j--){ 
       Complex z0 = new Complex(((double)i*3/size)-1.5,1.5-((double)j*3/size)); 
       prisoner = true; 

       for(int k=0;k<1000;k++){ 
        z0 = z0.squared(); 
        z0 = z0.add(c); 

        if(z0.dist()>2){ 
         prisoner = false; 
         break; 
        } 
       } 
       if(!prisoner){ 
        pixelColorBGR[0]=0; pixelColorBGR[1]=0; pixelColorBGR[2]=0; 
        output.write(pixelColorBGR); 
       }if(prisoner){ 
        pixelColorBGR[0]= (byte) 0xFF; pixelColorBGR[1]=(byte) 0xFF; pixelColorBGR[2]=(byte) 0xFF; 
        output.write(pixelColorBGR); 
       } 
      } 
     } 
     output.close(); 
    } 
} 

提前感謝!

+0

請爲此錯誤消息添加有關提前結束文件的完整堆棧跟蹤。 – VGR

+0

好吧,當我試圖用linux默認圖像查看器打開輸出文件時,會發生這種情況,所以只有關於文件過早結束的簡短錯誤消息,沒有什麼比這更簡單了。 – Lisu

回答

0

標題中的所有數字必須是little-endian。例如,當將54表示爲四個字節時,這四個字節必須是54,0,0,0。爲了將24表示爲兩個字節,兩個字節必須是24,0。

請注意,每行像素必須填充到4個字節的精確倍數。只要size是1000的倍數,這不會造成問題,但是如果您打算接受任意大小,則需要在計算大小時以及完成每行像素的填充時考慮填充。

與您的問題無關,但值得注意的是,Windows位圖以相反的順序包含其行。如果將圖像高度指定爲位圖標題中的正數,則需要先寫入最後一行,然後再寫入倒數第二行,依此類推。但是,如果在標題中將圖像高度指定爲負數(即-size),則可以按照從上到下的順序寫出行。 (對於Julia集合,這可能不是那麼重要。)