-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpixelate.mjs
More file actions
37 lines (32 loc) · 1.2 KB
/
Copy pathpixelate.mjs
File metadata and controls
37 lines (32 loc) · 1.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#!/usr/bin/env node
import sharp from 'sharp';
import { parseArgs } from 'node:util';
const { values } = parseArgs({
options: {
in: { type: 'string' },
out: { type: 'string' },
size: { type: 'string', default: '64' },
},
});
if (!values.in || !values.out) {
console.error('Usage: node scripts/pixelate.mjs --in input.png --out output.png [--size 128]');
process.exit(1);
}
const s = Number(values.size);
// Each source frame comes from an independent AI generation, so the character
// isn't framed identically canvas-to-canvas (e.g. one walk frame may sit 30px
// further right than another). Trim the transparent padding down to the actual
// character silhouette first, then re-contain it bottom-anchored + horizontally
// centered — this keeps every frame's visual feet/ground-contact point at the
// same canvas position, matching CamperRenderer's fixed anchor(0.5, 1).
await sharp(values.in)
.trim({ background: { r: 0, g: 0, b: 0, alpha: 0 } })
.resize(s, s, {
kernel: sharp.kernel.nearest,
fit: 'contain',
position: 'bottom',
background: { r: 0, g: 0, b: 0, alpha: 0 },
})
.png()
.toFile(values.out);
console.log(`Saved: ${values.out} (${s}x${s})`);