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

    你可能感兴趣的文章
    NUC1077 Humble Numbers【数学计算+打表】
    查看>>
    NuGet Gallery 开源项目快速入门指南
    查看>>
    NuGet(微软.NET开发平台的软件包管理工具)在VisualStudio中的安装的使用
    查看>>
    nuget.org 无法加载源 https://api.nuget.org/v3/index.json 的服务索引
    查看>>
    Nuget~管理自己的包包
    查看>>
    NuGet学习笔记001---了解使用NuGet给net快速获取引用
    查看>>
    nullnullHuge Pages
    查看>>
    NullPointerException Cannot invoke setSkipOutputConversion(boolean) because functionToInvoke is null
    查看>>
    null可以转换成任意非基本类型(int/short/long/float/boolean/byte/double/char以外)
    查看>>
    Numix Core 开源项目教程
    查看>>
    NumPy 或 Pandas:将数组类型保持为整数,同时具有 NaN 值
    查看>>
    numpy 或 scipy 有哪些可能的计算可以返回 NaN?
    查看>>
    numpy 数组 dtype 在 Windows 10 64 位机器中默认为 int32
    查看>>
    numpy 数组与矩阵的乘法理解
    查看>>
    NumPy 数组拼接方法-ChatGPT4o作答
    查看>>
    numpy 用法
    查看>>
    Numpy 科学计算库详解
    查看>>
    Numpy.fft.fft和numpy.fft.fftfreq有什么不同
    查看>>
    Numpy.ndarray对象不可调用
    查看>>
    numpy、cv2等操作图片基本操作
    查看>>