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

    你可能感兴趣的文章
    Oracle 写存储过程的一个模板还有一些基本的知识点
    查看>>
    Oracle 创建 DBLink 的方法
    查看>>
    oracle 创建字段自增长——两种实现方式汇总
    查看>>
    Oracle 升级10.2.0.5.4 OPatch 报错Patch 12419392 Optional component(s) missing 解决方法
    查看>>
    oracle 可传输的表空间:rman
    查看>>
    Oracle 启动监听命令
    查看>>
    oracle 学习
    查看>>
    oracle 定义双重循环例子
    查看>>
    ORACLE 客户端工具连接oracle 12504
    查看>>
    oracle 查询clob
    查看>>
    oracle 行转列
    查看>>
    Oracle 表
    查看>>
    Oracle 递归
    查看>>
    oracle 逻辑优化,提升高度,综合SQL上下文进行逻辑优化
    查看>>
    oracle 闪回关闭,关闭闪回即disable flashback的操作步骤
    查看>>
    oracle 限制用户并行,insert /*parallel */ 到不同用户,并行起不来的问题
    查看>>
    oracle--用户,权限,角色的管理
    查看>>
    oracle00205报错,Oracle控制文件损坏报错场景
    查看>>
    Oracle10g EM乱码之快速解决
    查看>>
    Oracle10g下载地址--多平台下的32位和64位
    查看>>