源码分享-彩色/灰度保存二维数组值为BMP图片

源码中实现了一个功能:能够把二维数组的值,保存在BMP图片中。从而形象的观察数据峰值等在数组中的分布情况。实现基于Java,不依赖任何第三方库。

默认生成灰度图,也可生成彩色图。数组的值取值范围0-255(彩色的图建议取值范围0-192,即红到紫的颜色部分)。

图片效果:(0->255)

调用示例:

import java.io.File;
import java.io.IOException;

public class Main {

    public static void main(String[] args) {
        byte[][] bitmap = new byte[100][256];
        for (byte[] x : bitmap) {
            for (int i = 0; i < x.length; i++) {
                x[i] = (byte) i;
            }
        }

        try {
            BitmapFile bitmapFile = new BitmapFile(bitmap);
            // bitmapFile.setGrayColors();
            bitmapFile.setHueColors();
            bitmapFile.drawBitmap(new File("test.bmp"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

实现源码:

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

class BitmapFile {
    private final int[] mColors = new int[256]; // 调色板
    private final byte[][] mBitmap;

    public BitmapFile(byte[][] bitmap) {
        mBitmap = bitmap;
        setGrayColors();
    }

    private static void writeShort(OutputStream os, short s) throws IOException {
        os.write((byte) (s & 0xFF));
        os.write((byte) ((s >> 8) & 0xFF));
    }

    private static void writeInt(OutputStream os, int i) throws IOException {
        os.write((byte) (i & 0xFF));
        os.write((byte) ((i >> 8) & 0xFF));
        os.write((byte) ((i >> 16) & 0xFF));
        os.write((byte) ((i >> 24) & 0xFF));
    }

    private static int rangeColor(int c) {
        if (c < 0) return 0;
        else if (c > 255) return 255;
        else return c;
    }

    private void writeFileHeader(OutputStream os) throws IOException {
        int size = ((mBitmap[0].length + 3) / 4 * 4) * mBitmap.length;
        int offset = 14 + 40 + 256 * 4;
        // 位图文件头,共14字节
        writeShort(os, (short) 0x4D42); // 文件标识
        writeInt(os, offset + size); // 文件大小
        writeInt(os, 0); // 保留
        writeInt(os, offset); // 从头到点阵数据的偏移
    }

    private void writeInfoHeader(OutputStream os) throws IOException {
        int size = ((mBitmap[0].length + 3) / 4 * 4) * mBitmap.length;
        // 位图信息头,共40字节
        writeInt(os, 40); // 位图信息头的大小
        writeInt(os, mBitmap[0].length); // 位图的宽度
        writeInt(os, mBitmap.length); // 位图的高度
        writeShort(os, (short) 1); // 颜色平面数
        writeShort(os, (short) 8); // 比特数/像素数
        writeInt(os, 0); // 压缩类型,BI_RGB(0)为不压缩
        writeInt(os, size); // 点阵数据大小
        writeInt(os, 0); // 水平分辨率
        writeInt(os, 0); // 垂直分辨率
        writeInt(os, 0); // 调色板的颜色数,为0则颜色数为2的biBitCount次方
        writeInt(os, 0); // 重要的颜色数,0代表所有颜色都重要
        // 调色板
        for (int i = 0; i < 256; i++) {
            writeInt(os, mColors[i]);
        }
    }

    private void writeBitmapData(OutputStream os) throws IOException {
        for (byte[] x : mBitmap) {
            os.write(x);
            switch (x.length % 4) {
                case 1: os.write((byte) 0);
                case 2: os.write((byte) 0);
                case 3: os.write((byte) 0);
                case 0:
                default: break;
            }
        }
    }

    public void setGrayColors() {
        for (int i = 0; i < 256; i++) {
            mColors[i] = i * 0x00010101;
        }
    }

    public void setHueColors(int saturate, int bright) {
        // HSB(HSV)颜色空间
        saturate = rangeColor(saturate);
        bright = rangeColor(bright);
        float s = saturate / 255f * bright;
        int r, g, b;
        for (int i = 0; i < 256; i++) {
            float hue = i / 256f * 6;
            float dh = hue - (int) hue;
            r = g = b = bright;
            if (hue < 1) { // 红->黄
                g -= s * (1 - dh);
                b -= s;
            } else if (hue < 2) { // 黄->绿
                r -= s * dh;
                b -= s;
            } else if (hue < 3) { // 绿->青
                r -= s;
                b -= s * (1 - dh);
            } else if (hue < 4) { // 青->蓝
                r -= s;
                g -= s * dh;
            } else if (hue < 5) { // 蓝->品红
                r -= s * (1 - dh);
                g -= s;
            } else { // 品红->红
                g -= s;
                b -= s * dh;
            }
            mColors[i] = (rangeColor(r) << 16) | (rangeColor(g) << 8) | rangeColor(b);
        }
    }

    public void setHueColors() {
        setHueColors(255, 255);
    }

    public void drawBitmap(OutputStream os) throws IOException {
        writeFileHeader(os);
        writeInfoHeader(os);
        writeBitmapData(os);
    }

    public void drawBitmap(File file) throws IOException {
        OutputStream os = new FileOutputStream(file);
        os = new BufferedOutputStream(os);
        drawBitmap(os);
        os.close();
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值