import { mkdtempSync, writeFileSync, readFileSync, rmSync } from 'node:fs' import { join } from 'node:path' import { tmpdir } from 'node:os' import { runFfmpeg } from '../ffmpeg' import { imageDimensions } from '../resolution' export async function fitStill(data: Buffer, width: number, height: number) { const dir=mkdtempSync(join(tmpdir(),'studio2-fit-')) try { const input=join(dir,'source'),output=join(dir,'fitted.png') writeFileSync(input,data) await runFfmpeg(['-y','-i',input,'-vf',`scale=${width}:${height}:force_original_aspect_ratio=decrease,pad=${width}:${height}:(ow-iw)/2:(oh-ih)/2:color=black,setsar=1`,'-frames:v','1',output]) return readFileSync(output) } finally { rmSync(dir,{recursive:true,force:true}) } } /** Only scale/pad when the still's aspect truly differs from the job canvas. * A matching frame (typical extend handoff) must reach Comfy byte-identical. */ export function needsFit(data: Buffer, width: number, height: number) { const size = imageDimensions(data) if (!size?.width || !size?.height) return true if (size.width === width && size.height === height) return false const target = width / height, actual = size.width / size.height return Math.abs(target - actual) > 0.01 }