提问人:Andres Ordonez 提问时间:9/2/2023 更新时间:9/4/2023 访问量:66
在 Java 中读取 BMP 标头 [duplicate]
reading BMP header in Java [duplicate]
问:
我想读取 BMP 图像的标题,以便当一个人写入图像 bmp 的路径时,它会显示:
- 文件大小(以字节为单位)
- 宽度(以像素为单位)
- 高度(以像素为单位)
我正在研究 Java,老师建议使用 FileInputStream 和 FileOutputStream。
答:
1赞
Reilas
9/2/2023
#1
"...我想阅读BMP图像的标题......”
这是关于位图图像格式的维基百科文章,特别是文件头部分。
维基百科 – BMP 文件格式 – 位图文件头。
宽度和高度的字节偏移量为 18 和 22。
"...老师建议使用 FileInputStream 和 FileOutputStream”
可以使用 InputStream#readNBytes 方法获取数据的前 n 个字节。在这种情况下,n + 4 自最后一个字段以来是 4 个字节。
try (FileInputStream stream = new FileInputStream("image.bmp")) {
byte[] b = stream.readNBytes(0x32 + 4);
}
"...当一个人写入图像 BMP 的路径时,它会显示:
- 文件大小(以字节为单位)
- 宽度(以像素为单位)
- 高度(以像素为单位)
..."
您可以利用 ByteBuffer 类来转换数值。
我正在使用以下 NASA 位图图像。
NASA – SVS – ID 13326 – frame_0001.bmp (3840×3840) 的帧文件索引。
try (FileInputStream stream = new FileInputStream("files/frame_0001.bmp")) {
byte[] b = stream.readNBytes(0x32 + 4);
ByteBuffer bb = ByteBuffer.allocate(b.length);
for (byte x : b) bb.put((byte) (x & 0xff));
bb.order(ByteOrder.LITTLE_ENDIAN);
String id;
int size, sizeB, offset, width, height, planes, bpp,
hSize, compression, image, h_ppm, v_ppm, colors, important;
byte[] reserved1, reserved2;
id = new String(Arrays.copyOfRange(b, 0, 2));
bb.position(2);
size = bb.getInt();
reserved1 = Arrays.copyOfRange(b, 6, 8);
reserved2 = Arrays.copyOfRange(b, 8, 10);
bb.position(10);
offset = bb.getInt();
hSize = bb.getInt();
width = bb.getInt();
height = bb.getInt();
planes = bb.getChar();
bpp = bb.getChar();
compression = bb.getInt();
sizeB = bb.getInt();
h_ppm = bb.getInt();
v_ppm = bb.getInt();
colors = bb.getInt();
important = bb.getInt();
String string
= "b= %,d (0x%1$x), %s%n".formatted(b.length, Arrays.toString(b))
+ "id= '%s', %s%n".formatted(id, Arrays.toString(id.getBytes()))
+ "size= %,d%n".formatted(size)
+ "reserved1= %s%n".formatted(Arrays.toString(reserved1))
+ "reserved2= %s%n".formatted(Arrays.toString(reserved2))
+ "offset= %,d (0x%1$x)%n".formatted(offset)
+ "hSize= %,d (0x%1$x)%n".formatted(hSize)
+ "width= %,d%n".formatted(width)
+ "height= %,d%n".formatted(height)
+ "planes= %,d%n".formatted(planes)
+ "bpp= %,d%n".formatted(bpp)
+ "compression= %d%n".formatted(compression)
+ "sizeB= %,d%n".formatted(sizeB)
+ "h_ppm= %d%n".formatted(h_ppm)
+ "v_ppm= %d%n".formatted(v_ppm)
+ "colors= %d%n".formatted(colors)
+ "important= %d%n".formatted(important);
System.out.println(string);
}
输出
b= 54 (0x36), [66, 77, 54, 4, -31, 0, 0, 0, 0, 0, 54, 4, 0, 0, 40, 0, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 1, 0, 8, 0, 0, 0, 0, 0, 0, 0, -31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
id= 'BM', [66, 77]
size= 14,746,678
reserved1= [0, 0]
reserved2= [0, 0]
offset= 1,078 (0x436)
hSize= 40 (0x28)
width= 3,840
height= 3,840
planes= 1
bpp= 8
compression= 0
sizeB= 14,745,600
h_ppm= 0
v_ppm= 0
colors= 0
important= 0
另一种方法是使用按位和移位操作。
评论