import { isImageData } from "./isImageData" /** * 把 ImageData 编码成二进制数据(Blob) * ImageData 是包含图片像素数据数组和宽高信息的对象 * @param data ImageData 或 HTMLImageElement * @param type 图片格式如 image/gif, image/png, image/jpeg, image/webp * @param quality 质量参数 0~1(toDataURL 为 jpeg, webp 用的的质量参数) * @return {Promise} */ export async function imageEncode( data: ImageData | HTMLImageElement | ImageBitmap, type = "image/png", quality?: number ): Promise { let canvas!: HTMLCanvasElement let ctx!: CanvasRenderingContext2D if (!canvas) { canvas = document.createElement("canvas") ctx = canvas.getContext("2d") if (!ctx) throw new Error("Could not create canvas context") } canvas.width = data.width canvas.height = data.height ctx.clearRect(0, 0, canvas.width, canvas.height) if (isImageData(data)) { ctx.putImageData(data, 0, 0) } else { ctx.drawImage(data, 0, 0) } let blob: Blob | null if ("toBlob" in canvas) { blob = await new Promise((re) => canvas.toBlob(re, type, quality)) } else { // Windows Edge const dataUrl = (canvas as HTMLCanvasElement).toDataURL(type, quality) const result = /data:([^;]+);base64,(.*)$/.exec(dataUrl) if (!result) throw Error("Data URL reading failed") const outputType = result[1] const binaryStr = atob(result[2]) const data = new Uint8Array(binaryStr.length) for (let i = 0; i < data.length; i += 1) { data[i] = binaryStr.charCodeAt(i) } blob = new Blob([data], { type: outputType }) } // canvas.remove() if (!blob) throw Error("Encoding failed") return blob }