jpg -> apng
graph LR
jpg链接 -->|下载远端图片 loadImage| jpg的buffer --> |将JPG转换为PNG convertJpgToPngBuffer| png --> |把png Buffer转换成原始RGBA图像数据 getPngFrame| rgba -->|UPNG.js生成APNG| UPNG.encode
// 下载远端jpg图片
function loadImage(url) {
return new Promise((resolve, reject) => {
https.get(url, (res) => {
const data = [];
res.on('data', (chunk) => {
data.push(chunk);
});
res.on('end', () => {
resolve(Buffer.concat(data));
});
}).on('error', (err) => {
reject(err);
});
});
}
// 将JPG转换为PNG
const sharp = require('sharp');
async function convertJpgToPngBuffer(inputBuffer) {
const pngBuffer = await sharp(inputBuffer).resize(300, 300).png().toBuffer();
return pngBuffer;
}
// 把png Buffer转换成原始RGBA图像数据
const PNG = require('pngjs').PNG;
async function getPngFrame(pngBuffer) {
return new Promise((resolve, reject) => {
const png = new PNG();
png.parse(pngBuffer, (error, data) => {
if (error) {
reject(error);
} else {
resolve(data.data.buffer);
}
});
});
}
// 使用UPNG.js生成APNG
// ⚠️ UPNG.encode 里面的 frames 接受的是RGBA图像数据,这个需要注意
const UPNG = require('upng-js');
const apngArrayBuffer = UPNG.encode(frames, width, height, 0, delays);
const apngBuffer = Buffer.from(apngArrayBuffer); // 转换buffer可以推送到阿里云oss中
apng
APNG(Animated Portable Network Graphics)是一种支持动画的图像文件格式,基于 PNG(Portable Network Graphics)文件格式。APNG是对原始的PNG格式的扩展,允许帧序列嵌入在单个文件中,这与GIF图像的动画支持类似,但它提供了更好的压缩、全色彩(不限制为256色)以及包含透明度信息。
Buffer/ArrayBuffer
Buffer
在 Node.js 中,Buffer 类是用于处理二进制数据流的一个全局对象。Buffer 类创建一个包含字节数组的存储空间,允许你在内存中存储原始数据,并对这些数据进行读写操作。它主要用于操作文件系统、网络通信、或任何其他的 I/O 操作中的数据流和缓冲区。
ArrayBuffer
ArrayBuffer 是 JavaScript 中的一种基本数据类型,用于表示固定长度的原始二进制数据缓冲区。
// node 打印 ArrayBuffer,
// const arrayBuffer = new ArrayBuffer(360000);
// console.log(arrayBuffer);
ArrayBuffer {
[Uint8Contents]: <ff 36 0a ff ff 36 0a ff ff 36 0a ff ff 36 0a ff ff 36 0a ff ff 36 0a ff fe 37 0a ff ff 36 09 ff ff 35 0a ff ff 36 0b ff ff 36 0a ff ff 36 0a ff fe 36 0a ff ff 36 09 ff ff 36 0a ff ff 36 0a ff ff 36 0b ff ff 36 0a ff ff 36 0a ff ff 36 0a ff fe 37 0a ff ff 36 0a ff ff 36 0a ff ff 36 0a ff ff 36 0a ff ... 359900 more bytes>,
byteLength: 360000
},
- ArrayBuffer 对象有 360000 字节的长度 (byteLength: 360000)。
Uint8Contents通常是描述ArrayBuffer内容时用到的内部属性,在某些调试环境或日志输出中可能会看到这个标识。它表示ArrayBuffer中的内容可以用一个Uint8Array来访问。Uint8Array是一个视图,它以8位无符号整数的形式展现ArrayBuffer中的二进制数据。这个 ArrayBuffer 可以通过 Uint8Array 或其他类型化数组访问,这些类型化数组可以提供对缓冲区中数据的视图,无需复制数据本身。- [Uint8Contents] 后面跟随的 <ff 36 0a ...> 表示了缓冲区中的内容,以十六进制形式展示。
- 要从 ArrayBuffer 中读取数据,通常会使用类型化数组。
const dataView = new Uint8Array(arrayBuffer);