24 lines
1.3 KiB
JavaScript
24 lines
1.3 KiB
JavaScript
import {readFileSync} from 'node:fs';
|
|
import {createHash} from 'node:crypto';
|
|
import path from 'node:path';
|
|
|
|
export function sha256(value) { return createHash('sha256').update(value).digest('hex'); }
|
|
|
|
export function imageFormat(bytes) {
|
|
if (bytes.length >= 24 && bytes.subarray(0, 8).equals(Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]))) {
|
|
return {mime: 'image/png', extension: 'png', width: bytes.readUInt32BE(16), height: bytes.readUInt32BE(20)};
|
|
}
|
|
if (bytes.length >= 3 && bytes[0] === 255 && bytes[1] === 216 && bytes[2] === 255) return {mime: 'image/jpeg', extension: 'jpg'};
|
|
if (bytes.length >= 12 && bytes.toString('ascii', 0, 4) === 'RIFF' && bytes.toString('ascii', 8, 12) === 'WEBP') return {mime: 'image/webp', extension: 'webp'};
|
|
throw new Error('图片数据不是支持的 PNG/JPEG/WebP 格式');
|
|
}
|
|
|
|
export function readImage(file, {pngOnly = false} = {}) {
|
|
const bytes = readFileSync(file);
|
|
const format = imageFormat(bytes);
|
|
if (pngOnly && (format.extension !== 'png' || !format.width || !format.height)) throw new Error('结构理解与局部画布当前要求非空 PNG 图片');
|
|
return {file: path.resolve(file), bytes, ...format, sha256: sha256(bytes)};
|
|
}
|
|
|
|
export function dataUrl(image) { return `data:${image.mime};base64,${image.bytes.toString('base64')}`; }
|