博客
关于我
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/

    你可能感兴趣的文章
    poj 3539 Elevator——同余类bfs
    查看>>
    Qt笔记——官方文档全局定义(三)Macros宏
    查看>>
    poj 3628 Bookshelf 2
    查看>>
    Qt笔记——官方文档全局定义(一)Types数据类型
    查看>>
    POJ 3670 DP LIS?
    查看>>
    POJ 3683 Priest John's Busiest Day (算竞进阶习题)
    查看>>
    POJ 3988 Selecting courses
    查看>>
    POJ 4020 NEERC John's inversion 贪心+归并求逆序对
    查看>>
    poj 4044 Score Sequence(暴力)
    查看>>
    POJ 基础数据结构
    查看>>
    POJ 题目3020 Antenna Placement(二分图)
    查看>>
    Poj(1797) Dijkstra对松弛条件的变形
    查看>>
    SpringBoot为什么不需要xml配置文件?
    查看>>
    POJ--2391--Ombrophobic Bovines【分割点+Floyd+Dinic优化+二分法答案】最大网络流量
    查看>>
    Qt笔记——SQLite初探QSqlDatabase QSqlQuery
    查看>>
    POJ-1163-The Triangle
    查看>>
    POJ-Fence Repair 哈夫曼树
    查看>>
    poj1061 - 同余方程,二元一次不定方程
    查看>>
    Qt笔记——SQLite再探
    查看>>
    poj1068Parencodings
    查看>>