1.2.0 • Published 2 months ago

binary-bmp v1.2.0

Weekly downloads
286
License
ISC
Repository
github
Last release
2 months ago

logo

Binary Bmp 是纯 JS 编写的无依赖的位图文件生成器,可由像素数组canvas 对象生成单色、VGA、灰度、RGB、RGBA 位图文件。

安装

npm install binary-bmp

引入

ESM

import { make } from 'binary-bmp';

CJS

const { make } = require('binary-bmp');

HTML

<script src="./node_modules/binary-bmp/dist/index.iife.js"></script>
<script>
  const { make } = window.Bmp;
</script>

使用

import { make } from 'binary-bmp';

const uint8array = make({
  bits: 1, // 颜色位值
  width: 3, // 图片宽度
  height: 3, // 图片高度
  data: [ // 像素数据
    0,1,0,
    1,1,1,
    0,1,1,
  ],
});

位图可以分为以下几种:

名称颜色位值颜色数量数组元素取值范围颜色表数组元素含义
单色位图120 ~ 1颜色表索引
VGA位图4160 ~ 15颜色表索引
灰度位图82560 ~ 255颜色表索引
RGB位图24.......0 ~ 255RGB分量值
RGBA位图32.......0 ~ 255RGBA分量值

单色位图

单色位图的颜色位值为 1bit,只能表示 2^1=2 种颜色,可用于热敏打印机。所以 data 数组中元素为 01 两种,默认 0 表示黑色 1 表示白色:

const binary = make({
  bits: 1,
  width: 3,
  height: 3,
  data: [
    0,1,0,
    1,1,1,
    0,1,1,
  ],
});

npm.io

但是我们可以使用 palette 属性自定义颜色表:

const binaryPalette = make({
  bits: 1,
  width: 3,
  height: 3,
  data: [
    0,1,0,
    1,1,1,
    0,1,1,
  ],
  palette: [
    '#F44336',
    '#FFFFFF',
  ],
});

npm.io

此时 0 表示颜色表中索引为 0 的颜色即 #F44336(红色),1 表示颜色表中索引为 1 的颜色即 #FFFFFF(白色)


VGA位图

VGA位图的颜色位值为 4bit,能表示 2^4=16 种颜色。所以 data 数组中元素取值范围为 0-15,默认 0 至 15 表示从黑色到白色均匀分布的16个颜色:

const vga = make({
  bits: 4,
  width: 4,
  height: 4,
  data: [
    0,1,2,3,
    4,5,6,7,
    8,9,10,11,
    12,13,14,15,
  ],
});

npm.io

VGA 位图也可以自定义颜色表:

const vgaPalette = make({
  bits: 4,
  width: 4,
  height: 4,
  data: [
    0,1,2,3,
    4,5,6,7,
    8,9,10,11,
    12,13,14,15,
  ],
  palette: [
    '#F44336',
    '#E91E63',
    '#9C27B0',
    '#673AB7',
    '#3F51B5',
    '#2196F3',
    '#03A9F4',
    '#00BCD4',
    '#009688',
    '#4CAF50',
    '#8BC34A',
    '#CDDC39',
    '#FFEB3B',
    '#FFC107',
    '#FF9800',
    '#FF5722',
  ],
});

npm.io


灰度位图

灰度位图的颜色位值为 8bit,能表示 2^8=256 种颜色,即我们常见的黑白图片。所以 data 数组中元素取值范围为 0-255,默认的 0 至 255 表示从黑色到白色均匀分布的256种颜色:

const grey = make({
  bits: 8,
  width: 4,
  height: 4,
  data: [
    0,17,34,51,
    68,85,102,119,
    136,153,170,187,
    204,221,238,255,
  ],
});

npm.io

灰度位图同样可以自定义颜色表。由于灰度位图能表示 2^8=256 种颜色,所以自定义颜色表中最多可能有256个颜色,代码太长故不在此展示。


RGB位图

RGB位图的颜色位值为 24bit,这 24bit 由 8bit + 8bit + 8bit 组成,表示一个像素点的 R(red)G(green)B(blue) 三个分量,即我们常见的彩色图片。所以 data 数组中元素取值范围为 0-255,每3个为一组按 RGB 的顺序表示一个像素点的颜色:

const rgb = make({
  bits: 24,
  width: 3,
  height: 1,
  data: [
    255,0,0, 255,255,0, 0,0,0,
  ],
});

npm.io

由于RGB位图的数据直接表示颜色值而不是颜色表索引,所以不再需要颜色表。


RGBA位图

RGBA位图颜色位值为 32bit,相较于 RGB 位图只多了一个 8bit 的 A(alpha) 分量来表示不透明度。data 数组每 4 个元素为一组按 RGBA 的顺序表示一个像素点的颜色:

const rgba = make({
  bits: 32,
  width: 3,
  height: 1,
  data: [
    255,0,0,0, 0,255,0,128, 0,0,255,255,
  ],
});

npm.io

同样的,RGBA位图没有颜色表。

Canvas转位图

支持将 canvas 转为 RGBA 位图、灰度位图、单色位图:

import { fromCanvas } from 'binary-bmp';

const canvas = document.getElementById('canvas-id');

const rgba = fromCanvas(32, canvas);
const grey = fromCanvas(8, canvas);
const binary = fromCanvas(1, canvas);

const blob = new Blob([rgba], { type: 'image/bmp' });
const url = URL.createObjectURL(blob);

canvas

同时兼容 node-canvas 等实现了 Canvas API 的库。

自定义颜色表

只有1位单色位图、4位VGA位图、8位灰度位图有自定义颜色表(调色板)。颜色表中最多有 2^n 个颜色,n 为位图的颜色位值。 例如4位VGA位图的自定义颜色表中最多可以有2^4=16个颜色。具体数量可以少于16个,例如 data 数组中最大的索引只到 7,那么自定义 7 个颜色就足够了,当自定义颜色少于 7 个时,剩下的颜色会被填充为黑色。

增强代码的可读性

由于需要记住每种位图的颜色位值很麻烦,维护代码时也很容易忘记每种颜色位值代表的位图种类,所以包导出了5个以位图名称命名的位图颜色位值:

import { BINARY, VGA, GREY, RGB, RGBA } from 'binary-bmp';

BINARY === 1
VGA    === 4
GREY   === 8
RGB    === 24
RGBA   === 32

API

/** 生成位图文件 */
export function make(options: IOption): Uint8Array;

/** 从类Canvas对象生成位图文件 */
export function fromCanvas(bits: number, canvas: ICanvasLike): Uint8Array;

interface IOption {
  bits: number,
  width: number,
  height: number,
  palette?: string[],
  data: Indexable<number>,
}

interface Indexable<T> {
  [index: number]: T;
}

interface ICanvasLike {
  width: number;
	height: number;
  getContext(contextId: '2d'): {
    getImageData(sx: number, sy: number, sw: number, sh: number): {
      readonly width: number;
      readonly height: number;
      readonly data: Uint8ClampedArray;
    };
  };
}

示例

更多使用方法请参考本仓库 examples 目录下的例子: