博客
关于我
BMP图存储—代码实现
阅读量:793 次
发布时间:2019-03-24

本文共 3206 字,大约阅读时间需要 10 分钟。

BMP图像存储(Java实现)

作为一名开发人员,我在研究如何在Java中实现BMP图像存储时遇到了许多挑战。本文将详细解释BMP图像的存储方式,并提供相应的代码实现。


一、24色位图的存储结构

BMP文件的存储结构可以分为以下几个部分:

  • BMP文件头

    包含指示BMP文件类型的标记 (82 4D) 和文件大小信息。

  • 位图信息头

    包含位图的宽度、高度、颜色数以及像素信息等参数。

  • 颜色索引表

    存储使用的颜色数组,这部分与实际使用的颜色数有关。

  • 位图数据

    存储实际的像素数据。


  • 二、24色位图的代码实现

    1. BMP文件头代码详解

    文件头是存储标记和文件大小的关键部分。以下是实现代码:

    public void saveBMP(BufferedOutputStream ops) throws IOException {    ops.write('B'); // 标记 B    ops.write('M'); // 标记 M    int size = 14 + 40 + height * width * 3 + ((4 - (width * 3 % 4)) * height); // 文件总大小    writeInt(ops, size);    writeShort(ops, (short) 0); // 信息偏移量    writeShort(ops, (short) 0); // 单位偏移量    writeInt(ops, 54); // 偏移量指向图像数据区}
    • size计算
      公式解析:
      • 14:文件头大小
      • 40:位图信息头大小
      • height * width * 3:每个像素占3字节(红、绿、蓝),总字节数
      • ((4 - (width * 3 % 4)) * height):比特补充部分(确保每行的字节数为4的倍数)

    2. 位图信息头代码详解

    位图信息头包含了位图的宽度、高度以及颜色信息。

    public void savebmpInfo(BufferedOutputStream ops) throws IOException {    writeInt(ops, 40); // 位图信息头大小    writeInt(ops, width); // 位图宽度    writeInt(ops, height); // 位图高度    writeShort(ops, (short) 1); // 颜色数    writeShort(ops, (short) 24); // 像素数    writeInt(ops, 0); // 无压缩信息    writeInt(ops, size - 54); // 偏移量指向颜色索引表    writeInt(ops, 0); // 水平分辨率(缺省)    writeInt(ops, 0); // 垂直分辨率(缺省)    writeInt(ops, 2); // 当前使用的颜色索引数    writeInt(ops, 2); // 当前使用的颜色索引数}

    3. 位图数据存储代码详解

    位图数据是存储像素信息的核心部分。

    public void savebmpData(BufferedOutputStream ops) throws IOException {    int m = 4 - (width * 3 % 4);    if (m > 0) {        System.out.println("补充字节数:" + m);    }    int[][] imgData = new int[width][height];    for (int i = 0; i < width; i++) {        for (int j = 0; j < height; j++) {            imgData[i][j] = image.getRGB(i, j); // 获取像素颜色值        }    }    for (int i = height - 1; i >= 0; i--) {        for (int j = 0; j < width; j++) {            int t = imgData[j][i];            writeColor(ops, t);        }    }    for (int k = 0; k < m; k++) {        ops.write(0);    }}

    三、问题与解决

    在实现过程中,主要遇到的问题包括:

  • 文件大小计算错误

    最终确认文件大小必须包含所有部分,避免遗漏。

  • 颜色写入顺序问题

    确保颜色的红、绿、蓝分量按正确顺序写入文件。

  • 比特补充处理不当

    需要确保每行的字节数符合4字节的倍数要求。


  • 四、单色位图的存储

    单色位图与24色位图的主要区别在于颜色索引表的存在。以下是实现代码:

    public void saveBMP(BufferedOutputStream ops) throws IOException {    ops.write('B');    ops.write('M');    int size = 14 + 40 + 8 + (height * width);    writeInt(ops, size);    writeShort(ops, (short) 0);    writeShort(ops, (short) 0);    writeInt(ops, 62);}

    五、代码工具与配套方法

    为了提高开发效率,可以编写以下工具方法:

    private void writeShort(BufferedOutputStream ops, short t) throws IOException {    int c = (t >> 8) & 0xff;    int d = t & 0xff;    ops.write(d);    ops.write(c);}private void writeInt(BufferedOutputStream ops, int t) throws IOException {    int a = (t >> 24) & 0xff;    int b = (t >> 16) & 0xff;    int c = (t >> 8) & 0xff;    int d = t & 0xff;    ops.write(d);    ops.write(c);    ops.write(b);    ops.write(a);}private byte[] divide(int num) {    byte[] bytes = new byte[4];    bytes[0] = (byte) (num & 0xff);    bytes[1] = (byte) ((num >> 8) & 0xff);    bytes[2] = (byte) ((num >> 16) & 0xff);    bytes[3] = (byte) ((num >> 24) & 0xff);    return bytes;}private int toGray(int t) {    int r = (t >> 16) & 0xff;    int g = (t >> 8) & 0xff;    int b = t & 0xff;    int gray = (int) (r * 0.3 + g * 0.59 + b * 0.11);    return gray;}

    通过以上详细的实现和优化,可以有效解决BMP图像存储问题。

    转载地址:http://bjekk.baihongyu.com/

    你可能感兴趣的文章
    mysql中kill掉所有锁表的进程
    查看>>
    mysql中like % %模糊查询
    查看>>
    MySql中mvcc学习记录
    查看>>
    mysql中null和空字符串的区别与问题!
    查看>>