Java: Saving big .bmp files with FileOutputStream

[亡魂溺海] 提交于 2019-12-11 05:04:56

问题


I'm trying to write an application generating and saving high resolution images of Julia sets, but I've got a problem. My code is creating a file with size almost corresponding to what (in my opinion) it should be, but when I try to open it, there's an error message about premature end of file.

I'm basically taking a size*size square, then for each pixel of this square I'm calculating corresponding number from the complex plane (fragment from -1.5 - 1.5i to 1,5 + 1.5i), and after that I'm starting an algorithm determining whether it belongs to certain Julia set or not (I'm totally sure that it works correctly, so you don't have to worry about it).

I'd like to generate very high resolution (like 20k*20k pixels, at least) images, so I'd like to do it with some kind of output stream. I've generated such images with BufferedImage, ImageIO.write() and stuff like that, but these are not working with images approaching to 9k*9k pixels (JVM heap size issues). I'll just add, that it/s my first time when I try to create a file like this, byte-by-byte.

Here's my code:

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

Thanks in advance!


回答1:


All numbers in the headers must be little-endian. For instance, when representing 54 as four bytes, those four bytes must be 54, 0, 0, 0. To represent 24 as two bytes, the two bytes must be 24, 0.

Be aware that every row of pixels must be padded to an exact multiple of 4 bytes. This isn't causing a problem as long as size is a multiple of 1000, but if you plan to accept an arbitary size, you'll need to account for the padding in your size calculation and when you finish writing each row of pixels.

Something else that isn't related to your issue, but is worth noting, is that a Windows bitmap contains its rows in reverse order. If you specify the image height as a positive number in the bitmap header, you will need to write the last row first, then the second-to-last row, and so on. However, you can write out the rows in top-to-bottom order if you specify the image height as a negative number (that is, -size) in the header. (This may not be all that important for a Julia set.)



来源:https://stackoverflow.com/questions/19472175/java-saving-big-bmp-files-with-fileoutputstream

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!