Java中位图创建的错误

时间:2015-06-12 08:36:31

标签: java bitmap drawing bmp

我正在尝试从像素值的二维数组创建一个位图。我在互联网上找到了一些代码(取自http://forum.codecall.net/topic/62457-creating-a-bmp-image-in-java/):

List<List<T>>

现在我尝试使用以下代码创建大小为10x5的位图:

[XmlIgnore]
public int[, ,] Data { get; set; }

[XmlElement("Data"), Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public int[] DataDto
{
    get { /* flatten from Data */ }
    set { /* expand into Data */ }
}

我的结果是不正确的。我希望有一个10x5的灰色bmp,但相反,我看到图像中有一条黄色的垂直线。绘制较大的图像(100x50)时,我得到了这个:

enter image description here

看起来这些列被绘制为行。我不确定为什么会这样。我在源代码中找到了一些关于填充的内容,但我很难理解它是如何工作的。

任何人都可以解释这种行为吗?请注意,我没有使用Android,因此我无法使用import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class BMP { private final static int BMP_CODE = 19778; byte [] bytes; public void saveBMP(String filename, int [][] rgbValues){ try { FileOutputStream fos = new FileOutputStream(new File(filename)); bytes = new byte[54 + 3*rgbValues.length*rgbValues[0].length + getPadding(rgbValues[0].length)*rgbValues.length]; saveFileHeader(); saveInfoHeader(rgbValues.length, rgbValues[0].length); saveRgbQuad(); saveBitmapData(rgbValues); fos.write(bytes); fos.close(); } catch (FileNotFoundException e) { } catch (IOException e) { } } private void saveFileHeader() { byte[]a=intToByteCouple(BMP_CODE); bytes[0]=a[1]; bytes[1]=a[0]; a=intToFourBytes(bytes.length); bytes[5]=a[0]; bytes[4]=a[1]; bytes[3]=a[2]; bytes[2]=a[3]; //data offset bytes[10]=54; } private void saveInfoHeader(int height, int width) { bytes[14]=40; byte[]a=intToFourBytes(width); bytes[22]=a[3]; bytes[23]=a[2]; bytes[24]=a[1]; bytes[25]=a[0]; a=intToFourBytes(height); bytes[18]=a[3]; bytes[19]=a[2]; bytes[20]=a[1]; bytes[21]=a[0]; bytes[26]=1; bytes[28]=24; } private void saveRgbQuad() { } private void saveBitmapData(int[][]rgbValues) { int i; for(i=0;i<rgbValues.length;i++){ writeLine(i, rgbValues); } } private void writeLine(int row, int [][] rgbValues) { final int offset=54; final int rowLength=rgbValues[row].length; final int padding = getPadding(rgbValues[0].length); int i; for(i=0;i<rowLength;i++){ int rgb=rgbValues[row][i]; int temp=offset + 3*(i+rowLength*row) + row*padding; bytes[temp] = (byte) (rgb>>16); bytes[temp +1] = (byte) (rgb>>8); bytes[temp +2] = (byte) rgb; } i--; int temp=offset + 3*(i+rowLength*row) + row*padding+3; for(int j=0;j<padding;j++) bytes[temp +j]=0; } private byte[] intToByteCouple(int x){ byte [] array = new byte[2]; array[1]=(byte) x; array[0]=(byte) (x>>8); return array; } private byte[] intToFourBytes(int x){ byte [] array = new byte[4]; array[3]=(byte) x; array[2]=(byte) (x>>8); array[1]=(byte) (x>>16); array[0]=(byte) (x>>24); return array; } private int getPadding(int rowLength){ int padding = (3*rowLength)%4; if(padding!=0) padding=4-padding; return padding; } } 类。

1 个答案:

答案 0 :(得分:2)

在我看来,这段代码并没有按预期工作。

查看此部分,例如:

saveInfoHeader(rgbValues.length, rgbValues[0].length);

saveInfoHeader有这个签名:

saveInfoHeader(int height, int width)

所以,当你通过int[100][50];时,你应该得到bmp 身高100和宽度50

我认为这部分代码不正确:

byte[]a=intToFourBytes(width);
bytes[22]=a[3];
bytes[23]=a[2];
bytes[24]=a[1];
bytes[25]=a[0];

a=intToFourBytes(height);
bytes[18]=a[3];
bytes[19]=a[2];
bytes[20]=a[1];
bytes[21]=a[0];

通过BMP标准宽度应该在高度之前声明,这里宽度先前处理,但是(我想,通过编辑错误)它写的是更大的偏移量。

如果您将其更改为:

byte[]a=intToFourBytes(width);
bytes[18]=a[3];
bytes[19]=a[2];
bytes[20]=a[1];
bytes[21]=a[0];

a=intToFourBytes(height);
bytes[22]=a[3];
bytes[23]=a[2];
bytes[24]=a[1];
bytes[25]=a[0];

,结果你得到了这个结果:

enter image description here

您得到的图案是由于高度/宽度不匹配导致的错误计算的BMP填充的结果。