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

本文共 3284 字,大约阅读时间需要 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/

    你可能感兴趣的文章
    NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_配置binlog_使用处理器抓取binlog数据_实际操作01---大数据之Nifi工作笔记0040
    查看>>
    NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_配置数据路由_实现数据插入数据到目标数据库_实际操作03---大数据之Nifi工作笔记0042
    查看>>
    NIFI同步MySql数据_到SqlServer_错误_驱动程序无法通过使用安全套接字层(SSL)加密与SQL Server_Navicat连接SqlServer---大数据之Nifi工作笔记0047
    查看>>
    Nifi同步过程中报错create_time字段找不到_实际目标表和源表中没有这个字段---大数据之Nifi工作笔记0066
    查看>>
    NIFI大数据进阶_离线同步MySql数据到HDFS_02_实际操作_splitjson处理器_puthdfs处理器_querydatabasetable处理器---大数据之Nifi工作笔记0030
    查看>>
    NIFI大数据进阶_连接与关系_设置数据流负载均衡_设置背压_设置展现弯曲_介绍以及实际操作---大数据之Nifi工作笔记0027
    查看>>
    NIFI数据库同步_多表_特定表同时同步_实际操作_MySqlToMysql_可推广到其他数据库_Postgresql_Hbase_SqlServer等----大数据之Nifi工作笔记0053
    查看>>
    NIFI汉化_替换logo_二次开发_Idea编译NIFI最新源码_详细过程记录_全解析_Maven编译NIFI避坑指南001---大数据之Nifi工作笔记0068
    查看>>
    NIFI集群_内存溢出_CPU占用100%修复_GC overhead limit exceeded_NIFI: out of memory error ---大数据之Nifi工作笔记0017
    查看>>
    NIFI集群_队列Queue中数据无法清空_清除队列数据报错_无法删除queue_解决_集群中机器交替重启删除---大数据之Nifi工作笔记0061
    查看>>
    NIH发布包含10600张CT图像数据库 为AI算法测试铺路
    查看>>
    Nim教程【十二】
    查看>>
    Nim游戏
    查看>>
    NIO ByteBuffer实现原理
    查看>>
    Nio ByteBuffer组件读写指针切换原理与常用方法
    查看>>
    NIO Selector实现原理
    查看>>
    nio 中channel和buffer的基本使用
    查看>>
    NIO基于UDP协议的网络编程
    查看>>
    NISP一级,NISP二级报考说明,零基础入门到精通,收藏这篇就够了
    查看>>
    Nitrux 3.8 发布!性能全面提升,带来非凡体验
    查看>>