// 读取多字节整数 functionreadMultiByteInt() { let result = 0 while (true) { // 读取下一位 let next = bytes[ptr++] // 左移7位 => 低位7位补零 result = result << 7 // next & 0b01111111 表示最高位变0,其余位置保留 result = result | (next & 0b01111111) // 判断最高位是不是0,是的话结束。(肯定会有一个最高位为0的字节,作为多字节数结尾的字节) if (!(next & 0b10000000)) { return result } } }
//... //... // 紧接上个步骤 // 以 0 开始 if (readOctet() != 0) returnfalse // 第二位也是 0 if (readOctet() != 0) returnfalse // 读取宽度 let width = readMultiByteInt() // 读取高度 let height = readMultiByteInt()
以 426 为例,存储状态为两个字节:1000001100101010,分析状态如图:
剩下的数据就是图片的像素点了!
知道了宽高,画一个 canvas 画布,并 createImageData 拿到图片数据:
1 2 3 4 5 6 7
// 建立一个 canvas,并建立一个图片数据 let canvas = document.createElement('canvas') canvas.setAttribute('width', width) canvas.setAttribute('height', height) let ctx = canvas.getContext('2d') let imageData = ctx.createImageData(width, height) let data = imageData.data
// 设置图片数据 // rgba functionwrite(bit) { // 当前位不为0,则是白色,否则填充黑色 let color = bit ? 255 : 0 data[w++] = color // r data[w++] = color // g data[w++] = color // b data[w++] = 255// a 透明度,不透明 }
// 从上到下遍历每一行 for (let y = 0; y < height; ++y) { // 从左到右遍历每一列的像素点。 // 每一个字节有 8 位,可以填充8个像素点,所以每次循环 +8 for (let x = 0; x < width; x += 8) { // 一个字节 8 位 let bits = bytes[ptr++] // 计算填充位置 let w = (y * width + x) * 4
// 读取多字节整数 functionreadMultiByteInt() { let result = 0 while (true) { // 读取下一位 let next = bytes[ptr++] // 左移7位 => 低位7位补零 result = result << 7 // next & 0b01111111 表示最高位变0,其余位置保留 result = result | (next & 0b01111111) // 判断最高位是不是0,是的话结束。(肯定会有一个最高位为0的字节,作为多字节数结尾的字节) if (!(next & 0b10000000)) { return result } } }
try { // 以 0 开始 if (readOctet() != 0) returnfalse // 第二位也是 0 if (readOctet() != 0) returnfalse let width = readMultiByteInt() let height = readMultiByteInt() // 建立一个 canvas let canvas = document.createElement('canvas') canvas.setAttribute('width', width) canvas.setAttribute('height', height) let ctx = canvas.getContext('2d') let imageData = ctx.createImageData(width, height) let data = imageData.data // 设置图片数据 for (let y = 0; y < height; ++y) { for (let x = 0; x < width; x += 8) { let bits = bytes[ptr++] let w = (y * width + x) * 4 // rgba functionwrite(bit) { let color = bit ? 255 : 0 data[w++] = color data[w++] = color data[w++] = color data[w++] = 255// 透明度,不透明 }