1

我正在尝试编写一个应用程序来生成和保存Julia 集的高分辨率图像,但我遇到了问题。我的代码正在创建一个文件,其大小几乎与(在我看来)它应该的大小相对应,但是当我尝试打开它时,会出现关于文件过早结束的错误消息。

我基本上取一个大小*大小的正方形,然后对于这个正方形的每个像素,我从复平面计算相应的数字(从-1.5 - 1.5i 到 1,5 + 1.5i 的片段),然后我' m 开始一个算法来确定它是否属于某个 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();
    }
}

提前致谢!

4

1 回答 1

0

标头中的所有数字都必须是little-endian。例如,将 54 表示为四个字节时,这四个字节必须是 54, 0, 0, 0。要将 24 表示为两个字节,这两个字节必须是 24, 0。

请注意,每一行像素都必须填充为 4 字节的精确倍数。只要size是 1000 的倍数,这不会引起问题,但是如果您打算接受任意大小,则需要在大小计算中以及完成写入每一行像素时考虑填充。

与您的问题无关但值得注意的其他事情是 Windows 位图以相反的顺序包含其行。如果在位图标题中将图像高度指定为正数,则需要先写入最后一行,然后是倒数第二行,依此类推。-size但是,如果在标题中将图像高度指定为负数(即 ),则可以按从上到下的顺序写出行。(这对于 Julia 集来说可能并不是那么重要。)

于 2013-10-20T13:34:17.873 回答