import sharp from 'sharp' import xmlescape from 'xml-escape' import pixelWidth from 'string-pixel-width' import { fileURLToPath } from 'url' type SharpInput = | Buffer | ArrayBuffer | Uint8Array | Uint8ClampedArray | Int8Array | Uint16Array | Int16Array | Uint32Array | Int32Array | Float32Array | Float64Array | string export async function makeOgImage( previewBufferOrFilename: SharpInput, streamName: string ) { const imgWidth = 1200 const imgHeight = 627 const panelPadding = 20 const panelWidth = imgWidth - 2 * panelPadding const panelHeight = 80 let title = '/ ' + streamName const maxTitleSize = 750 if (pixelWidth(title, { font: 'open sans', size: 48 }) > maxTitleSize) { while (pixelWidth(title, { font: 'open sans', size: 48 }) > maxTitleSize) { title = title.slice(0, -1) } title += '...' } const logo = await sharp( fileURLToPath( import.meta.resolve('#/assets/previews/images/speckle_logo_and_text.png') ) ) .resize({ height: panelHeight }) .toBuffer() const topPanel = Buffer.from(` ${xmlescape(title)} `) return await sharp(previewBufferOrFilename) .resize({ width: imgWidth, height: imgHeight }) .composite([ { input: topPanel, top: 0, left: 0 }, { input: logo, left: panelPadding + 10, top: panelPadding } ]) .png() .toBuffer() }