mirror of
https://github.com/smogon/sprites.git
synced 2026-08-20 00:34:22 -05:00
add tools/trim
This commit is contained in:
5
pnpm-lock.yaml
generated
5
pnpm-lock.yaml
generated
@@ -17,6 +17,11 @@ importers:
|
||||
commander: ^5.0.0
|
||||
make-promises-safe: ^5.1.0
|
||||
spritesmith: ^3.4.0
|
||||
tools/trim:
|
||||
dependencies:
|
||||
commander: 5.1.0
|
||||
specifiers:
|
||||
commander: ^5.1.0
|
||||
tools/tupctime:
|
||||
dependencies:
|
||||
better-sqlite3: 7.0.1
|
||||
|
||||
@@ -3,3 +3,4 @@ packages:
|
||||
- 'tools/tupctime'
|
||||
- 'tools/deploy'
|
||||
- 'tools/deflopt'
|
||||
- 'tools/trim'
|
||||
|
||||
37
tools/trim/image.js
Normal file
37
tools/trim/image.js
Normal file
@@ -0,0 +1,37 @@
|
||||
|
||||
import cp from 'child_process';
|
||||
|
||||
export function getDims(input) {
|
||||
const info = cp.execFileSync('convert', [input, '-format', "%w+%h+%@", 'info:'],
|
||||
{encoding:'utf8'});
|
||||
|
||||
const [imageWidth, imageHeight, width, height, left, top] =
|
||||
info.split(/x|\+/g).map(dim => parseInt(dim));
|
||||
|
||||
const right = imageWidth - (left + width);
|
||||
const bottom = imageHeight - (top + height);
|
||||
|
||||
return {
|
||||
width,
|
||||
height,
|
||||
left,
|
||||
top,
|
||||
right,
|
||||
bottom
|
||||
}
|
||||
}
|
||||
|
||||
export function crop(input, {width, height, left, top}, output) {
|
||||
cp.execFileSync('convert', [input, '+repage', '-crop', `${width}x${height}+${left}+${top}`, output]);
|
||||
}
|
||||
|
||||
// Trim, preserving displacement from center
|
||||
// Returns crop coords
|
||||
export function losslessTrim(dims) {
|
||||
return {
|
||||
left: Math.min(dims.left, dims.right),
|
||||
width: dims.width + Math.abs(dims.left - dims.right),
|
||||
top: Math.min(dims.top, dims.bottom),
|
||||
height: dims.height + Math.abs(dims.top - dims.bottom),
|
||||
}
|
||||
}
|
||||
41
tools/trim/index.js
Normal file
41
tools/trim/index.js
Normal file
@@ -0,0 +1,41 @@
|
||||
|
||||
import program from 'commander';
|
||||
import * as image from './image.js';
|
||||
|
||||
program
|
||||
.option('-c, --check', 'Check only')
|
||||
.option('-v, --verbose', 'Print info')
|
||||
.option('-f, --force', 'Force write even when already cropped')
|
||||
.parse(process.argv);
|
||||
|
||||
let retVal = 0;
|
||||
|
||||
for (const file of program.args) {
|
||||
const dims = image.getDims(file);
|
||||
const alreadyCropped = (dims.left === 0 || dims.right === 0) &&
|
||||
(dims.top === 0 || dims.bottom === 0);
|
||||
|
||||
if (program.verbose) {
|
||||
let msg = `${file}: ${dims.width}x${dims.height}, `;
|
||||
if (alreadyCropped) {
|
||||
msg += `displacement horiz ${dims.left - dims.right}, vert ${dims.top - dims.bottom}`;
|
||||
} else {
|
||||
msg += `padding left ${dims.left}, top ${dims.top}, right ${dims.right}, bottom ${dims.bottom}`;
|
||||
}
|
||||
console.log(msg);
|
||||
}
|
||||
|
||||
if (program.check && !alreadyCropped) {
|
||||
retVal = 1;
|
||||
if (!program.verbose) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!program.check && (!alreadyCropped || program.force)) {
|
||||
const trimDims = image.losslessTrim(dims);
|
||||
image.crop(file, trimDims, file);
|
||||
}
|
||||
}
|
||||
|
||||
process.exit(retVal);
|
||||
6
tools/trim/package.json
Normal file
6
tools/trim/package.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"commander": "^5.1.0"
|
||||
},
|
||||
"type": "module"
|
||||
}
|
||||
Reference in New Issue
Block a user