返回 oh-my-ppt
png-stitch.ts
根目录 / src / main / io / thumbnails / png-stitch.ts
1 import { PNG } from 'pngjs'
2
3 /**
4 * 把多张宽度相同的 PNG 纵向无缝拼接成一张长图,返回新 PNG 的 Buffer。
5 *
6 * PNG 内部像素经过「逐行过滤 + zlib 压缩」,不能直接首尾相接;这里逐张解码出
7 * 原始 RGBA 像素,按页顺序纵向块拷贝到一块总画布,再重新编码为单张 PNG。
8 * 同一个 session 的所有页面共用 slideSize,宽度恒定,因此只累加高度。
9 */
10 export function stitchPngBuffersVertical(buffers: Buffer[]): Buffer {
11 if (buffers.length === 0) {
12 throw new Error('没有可拼接的页面')
13 }
14
15 const images = buffers.map((buf) => PNG.sync.read(buf))
16 const width = images[0].width
17 for (const img of images) {
18 if (img.width !== width) {
19 throw new Error('页面宽度不一致,无法拼接长图')
20 }
21 }
22
23 const totalHeight = images.reduce((sum, img) => sum + img.height, 0)
24 const merged = new PNG({ width, height: totalHeight })
25
26 let yOffset = 0
27 for (const img of images) {
28 PNG.bitblt(img, merged, 0, 0, img.width, img.height, 0, yOffset)
29 yOffset += img.height
30 }
31
32 return PNG.sync.write(merged)
33 }
34
34 lines TYPESCRIPT