/** 把数据变成图片 */ export function imageEmbed(blob: Blob) {} /** * 把任意数据转化为像素数据(为了高宽比,会填充 0) */ export function imageEmbedBufferWrite(buffer: ArrayBuffer, options?: Partial): IImageData { options = Object.assign({ width: 128, blockSize: 1 }, options) let { blockSize, width } = options let dbits = buffer2dbits(buffer) let dbitsFilled = dbitsFill(dbits) let dataLen = dbitsFilled.length / 4 let height = Math.ceil(dataLen / 3 / width) // 最终数据长度 let finLen = width * height * 3 // 填充末尾 if (finLen > dataLen) { for (let i = 0, len = finLen - dataLen; i < len; i++) { dbitsFilled.push(0, 0, 0, 0) } } let data = dbits2buffer(dbitsFilled) let finData = dataAddAlpha(new Uint8ClampedArray(data)) if (options.blockSize == 1) { return { data: finData, width, height, } } else { return imageDataScale( { data: finData, width, height, }, blockSize ) } } /** 把 bit 对组合成字节 */ export function buffer2dbits(buffer: ArrayBuffer): number[] { let inputData = new Uint8Array(buffer) let dbits: number[] = [] inputData.forEach((byte, i) => { let s1 = byte >> 6 let s2 = (byte << 2) >> 6 let s3 = (byte << 4) >> 6 let s4 = (byte << 6) >> 6 dbits.push(s1, s2, s3, s4) }) return dbits } /** 把字节分割为 bit 对 */ export function dbits2buffer(dbits: number[]) { let len = dbits.length / 4 let outpuData = new Uint8Array(len) for (let i = 0; i < len; i++) { let index = i * 4 let s1 = dbits[index] << 6 let s2 = dbits[index + 1] << 4 let s3 = dbits[index + 2] << 2 let s4 = dbits[index + 3] let byte = s1 | s2 | s3 | s4 outpuData[i] = byte } return outpuData.buffer } /** bit 对按字节填充数据,一个字节 4 dbit,指定有效 bit 对数,剩下的填充 0 * @param dbit 有效 bit 对数 */ export function dbitsFill(dbits: number[], dbit = 3) { let newDbits: number[] = [] let len = dbits.length / dbit for (let i = 0; i < len; i++) { let index = i * dbit for (let j = 0; j < dbit; j++) { newDbits.push(dbits[index + j]) } let fillLen = 4 - dbit for (let j = 0; j < fillLen; j++) { newDbits.push(0) } } return newDbits } /** 提取填充过的 bit 对中的有效 bit 对 * @param dbit 有效 bit 对数 */ export function dbitsUnFill(dbits: number[], dbit = 3) { let newDbits: number[] = [] let len = dbits.length / 4 for (let i = 0; i < len; i++) { let index = i * 4 for (let j = 0; j < dbit; j++) { newDbits.push(dbits[index + j]) } } return newDbits } export interface IImageEmbedBufferOptions { width: number blockSize: number } export interface IImageData { data: Uint8ClampedArray height: number width: number } export function imageDataScale(imageData: IImageData, sacle = 8) { let newH = imageData.height * sacle let newW = imageData.width * sacle let newData = new Uint8ClampedArray(newH * newW * 4) let { width, height, data } = imageData for (let iy = 0, len = height; iy < len; iy++) { for (let ix = 0, len = width; ix < len; ix++) { let index = (iy * width + ix) * 4 let r = data[index] let g = data[index + 1] let b = data[index + 2] let a = data[index + 3] for (let i = 0; i < sacle; i++) { for (let j = 0; j < sacle; j++) { let newIndex = ((iy * sacle + i) * newW + (ix * sacle + j)) * 4 newData[newIndex] = r newData[newIndex + 1] = g newData[newIndex + 2] = b newData[newIndex + 3] = a } } } } return { data: newData, height: newH, width: newW, } } export function imageDataUnScale(imageData: IImageData, sacle = 8) { let newH = imageData.height / sacle let newW = imageData.width / sacle let newData = new Uint8ClampedArray(newH * newW * 4) let { width, height, data } = imageData for (let iy = 0, len = newH; iy < len; iy++) { for (let ix = 0, len = newW; ix < len; ix++) { let index = (iy * newW + ix) * 4 let r: number[] = [] let g: number[] = [] let b: number[] = [] let a: number[] = [] for (let i = 0; i < sacle; i++) { for (let j = 0; j < sacle; j++) { let oldIndex = ((iy * sacle + i) * width + (ix * sacle + j)) * 4 r.push(data[oldIndex]) g.push(data[oldIndex + 1]) b.push(data[oldIndex + 2]) a.push(data[oldIndex + 3]) } } newData[index] = r.reduce((a, b) => a + b) / r.length newData[index + 1] = g.reduce((a, b) => a + b) / g.length newData[index + 2] = b.reduce((a, b) => a + b) / b.length newData[index + 3] = a.reduce((a, b) => a + b) / a.length } } return { data: newData, height: newH, width: newW, } } export function dataAddAlpha(data: Uint8ClampedArray, value = 255) { let newLen = data.byteLength / 3 + data.byteLength let newData = new Uint8ClampedArray(newLen) for (let i = 0, len = data.byteLength / 3; i < len; i++) { let index = i * 3 let newIndex = i * 4 newData[newIndex] = data[index] newData[newIndex + 1] = data[index + 1] newData[newIndex + 2] = data[index + 2] newData[newIndex + 3] = 255 } return newData } export function dataRemoveAlpha(data: Uint8ClampedArray, value = 255) { let newLen = data.byteLength - data.byteLength / 4 let newData = new Uint8ClampedArray(newLen) for (let i = 0, len = data.byteLength / 3; i < len; i++) { let index = i * 4 let newIndex = i * 3 newData[newIndex] = data[index] newData[newIndex + 1] = data[index + 1] newData[newIndex + 2] = data[index + 2] } return newData }