screenshot-beautify 1.2.2 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +76 -20
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -99,16 +99,38 @@ async function extractDominantColor(imagePath) {
|
|
|
99
99
|
const isNeutral = avgSaturation < 25 || hsl.s < 15 || isGreyish;
|
|
100
100
|
let color1Hsl, color2Hsl;
|
|
101
101
|
if (isNeutral) {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
102
|
+
const vibrantPairs = [
|
|
103
|
+
["#667eea", "#764ba2"],
|
|
104
|
+
// indigo → purple
|
|
105
|
+
["#f093fb", "#f5576c"],
|
|
106
|
+
// pink → coral
|
|
107
|
+
["#43e97b", "#38f9d7"],
|
|
108
|
+
// emerald → cyan
|
|
109
|
+
["#00c6fb", "#005bea"],
|
|
110
|
+
// sky → deep blue
|
|
111
|
+
["#e0c3fc", "#8ec5fc"],
|
|
112
|
+
// lavender → sky blue
|
|
113
|
+
["#ff9a9e", "#fad0c4"],
|
|
114
|
+
// salmon → peach
|
|
115
|
+
["#f12711", "#f5af19"],
|
|
116
|
+
// red → amber
|
|
117
|
+
["#d4fc79", "#96e6a1"],
|
|
118
|
+
// lime → mint
|
|
119
|
+
["#eecda3", "#ef629f"],
|
|
120
|
+
// gold → rose
|
|
121
|
+
["#fc00ff", "#00dbde"],
|
|
122
|
+
// magenta → teal
|
|
123
|
+
["#a1c4fd", "#c2e9fb"],
|
|
124
|
+
// periwinkle → ice blue
|
|
125
|
+
["#ffecd2", "#fcb69f"]
|
|
126
|
+
// cream → peach
|
|
127
|
+
];
|
|
128
|
+
let hash = 0;
|
|
129
|
+
for (let i = 0; i < data.length; i += info.channels * 3) {
|
|
130
|
+
hash = (hash << 5) - hash + data[i] | 0;
|
|
131
|
+
}
|
|
132
|
+
const index = Math.abs(hash) % vibrantPairs.length;
|
|
133
|
+
return vibrantPairs[index];
|
|
112
134
|
} else {
|
|
113
135
|
color1Hsl = {
|
|
114
136
|
h: hsl.h,
|
|
@@ -459,8 +481,16 @@ import chokidar from "chokidar";
|
|
|
459
481
|
import { resolve, basename, extname, join } from "path";
|
|
460
482
|
import { existsSync, mkdirSync } from "fs";
|
|
461
483
|
import { exec } from "child_process";
|
|
484
|
+
import { promisify } from "util";
|
|
462
485
|
var require2 = createRequire(import.meta.url);
|
|
463
486
|
var SysTray = require2("systray2").default;
|
|
487
|
+
var execAsync = promisify(exec);
|
|
488
|
+
async function copyImageToClipboard(imagePath) {
|
|
489
|
+
if (process.platform !== "darwin") return;
|
|
490
|
+
const absolutePath = resolve(imagePath);
|
|
491
|
+
const script = `osascript -e 'set the clipboard to (read (POSIX file "${absolutePath}") as \xABclass PNGf\xBB)'`;
|
|
492
|
+
await execAsync(script);
|
|
493
|
+
}
|
|
464
494
|
var IMAGE_EXTENSIONS = [".png", ".jpg", ".jpeg", ".webp", ".gif"];
|
|
465
495
|
function isImageFile(filePath) {
|
|
466
496
|
const ext = extname(filePath).toLowerCase();
|
|
@@ -489,6 +519,9 @@ async function processFile(filePath) {
|
|
|
489
519
|
});
|
|
490
520
|
processedCount++;
|
|
491
521
|
updateMenu();
|
|
522
|
+
if (config.copyToClipboard) {
|
|
523
|
+
await copyImageToClipboard(beautifiedPath);
|
|
524
|
+
}
|
|
492
525
|
if (config.deleteOriginal) {
|
|
493
526
|
const { unlink } = await import("fs/promises");
|
|
494
527
|
await unlink(filePath);
|
|
@@ -505,8 +538,8 @@ function startWatching() {
|
|
|
505
538
|
persistent: true,
|
|
506
539
|
ignoreInitial: true,
|
|
507
540
|
awaitWriteFinish: {
|
|
508
|
-
stabilityThreshold:
|
|
509
|
-
pollInterval:
|
|
541
|
+
stabilityThreshold: 200,
|
|
542
|
+
pollInterval: 50
|
|
510
543
|
}
|
|
511
544
|
});
|
|
512
545
|
watcher.on("ready", () => {
|
|
@@ -609,7 +642,8 @@ async function startTray(options) {
|
|
|
609
642
|
padding: options.padding || 80,
|
|
610
643
|
backgroundImage: options.backgroundImage,
|
|
611
644
|
backgroundPreset: options.backgroundPreset,
|
|
612
|
-
deleteOriginal: options.deleteOriginal || false
|
|
645
|
+
deleteOriginal: options.deleteOriginal || false,
|
|
646
|
+
copyToClipboard: options.copyToClipboard || false
|
|
613
647
|
};
|
|
614
648
|
if (!existsSync(config.sourcePath)) {
|
|
615
649
|
console.error(`Source directory does not exist: ${config.sourcePath}`);
|
|
@@ -625,6 +659,18 @@ async function startTray(options) {
|
|
|
625
659
|
import { resolve as resolve2, basename as basename2, dirname, extname as extname2, join as join2 } from "path";
|
|
626
660
|
import chokidar2 from "chokidar";
|
|
627
661
|
import { existsSync as existsSync2, mkdirSync as mkdirSync2 } from "fs";
|
|
662
|
+
import { exec as exec2 } from "child_process";
|
|
663
|
+
import { promisify as promisify2 } from "util";
|
|
664
|
+
var execAsync2 = promisify2(exec2);
|
|
665
|
+
async function copyToClipboard(imagePath) {
|
|
666
|
+
if (process.platform !== "darwin") {
|
|
667
|
+
console.warn("Clipboard copy is only supported on macOS");
|
|
668
|
+
return;
|
|
669
|
+
}
|
|
670
|
+
const absolutePath = resolve2(imagePath);
|
|
671
|
+
const script = `osascript -e 'set the clipboard to (read (POSIX file "${absolutePath}") as \xABclass PNGf\xBB)'`;
|
|
672
|
+
await execAsync2(script);
|
|
673
|
+
}
|
|
628
674
|
var IMAGE_EXTENSIONS2 = [".png", ".jpg", ".jpeg", ".webp", ".gif"];
|
|
629
675
|
function isImageFile2(filePath) {
|
|
630
676
|
const ext = extname2(filePath).toLowerCase();
|
|
@@ -644,7 +690,7 @@ program.command("presets").description("List available background presets").acti
|
|
|
644
690
|
});
|
|
645
691
|
console.log("\nUsage: screenshot-beautify <input> --preset sunset");
|
|
646
692
|
});
|
|
647
|
-
program.command("watch <source> <output>").description("Watch a directory and auto-beautify new screenshots").option("--padding <number>", "Padding around the screenshot", "80").option("--background <path>", "Background image path").option("--preset <name>", "Background preset (run 'presets' to see options)").option("--delete-original", "Delete original file after beautifying", false).action(async (source, output, opts) => {
|
|
693
|
+
program.command("watch <source> <output>").description("Watch a directory and auto-beautify new screenshots").option("--padding <number>", "Padding around the screenshot", "80").option("--background <path>", "Background image path").option("--preset <name>", "Background preset (run 'presets' to see options)").option("--delete-original", "Delete original file after beautifying", false).option("--copy", "Copy beautified image to clipboard", false).action(async (source, output, opts) => {
|
|
648
694
|
try {
|
|
649
695
|
const sourcePath = resolve2(source);
|
|
650
696
|
const outputPath = resolve2(output);
|
|
@@ -662,7 +708,7 @@ program.command("watch <source> <output>").description("Watch a directory and au
|
|
|
662
708
|
console.log(`
|
|
663
709
|
\u{1F50D} Watching for screenshots in: ${sourcePath}`);
|
|
664
710
|
console.log(`\u{1F4C1} Beautified screenshots will be saved to: ${outputPath}`);
|
|
665
|
-
console.log(`\u2699\uFE0F Options: padding=${padding}${backgroundPreset ? `, preset=${backgroundPreset}` : ""}${backgroundImage ? `, background=${backgroundImage}` : ""}${opts.deleteOriginal ? ", delete-original=true" : ""}`);
|
|
711
|
+
console.log(`\u2699\uFE0F Options: padding=${padding}${backgroundPreset ? `, preset=${backgroundPreset}` : ""}${backgroundImage ? `, background=${backgroundImage}` : ""}${opts.deleteOriginal ? ", delete-original=true" : ""}${opts.copy ? ", copy-to-clipboard=true" : ""}`);
|
|
666
712
|
console.log(`
|
|
667
713
|
\u2705 File watcher is now running...`);
|
|
668
714
|
console.log(` Press Ctrl+C to stop
|
|
@@ -672,8 +718,8 @@ program.command("watch <source> <output>").description("Watch a directory and au
|
|
|
672
718
|
persistent: true,
|
|
673
719
|
ignoreInitial: true,
|
|
674
720
|
awaitWriteFinish: {
|
|
675
|
-
stabilityThreshold:
|
|
676
|
-
pollInterval:
|
|
721
|
+
stabilityThreshold: 200,
|
|
722
|
+
pollInterval: 50
|
|
677
723
|
}
|
|
678
724
|
});
|
|
679
725
|
const timestamp = () => (/* @__PURE__ */ new Date()).toLocaleTimeString();
|
|
@@ -687,6 +733,10 @@ program.command("watch <source> <output>").description("Watch a directory and au
|
|
|
687
733
|
console.log(`[${timestamp()}] \u{1F4F8} New screenshot detected: ${basename2(filePath)}`);
|
|
688
734
|
await beautify(filePath, beautifiedPath, { padding, backgroundImage, backgroundPreset });
|
|
689
735
|
console.log(`[${timestamp()}] \u2728 Beautified: ${basename2(beautifiedPath)}`);
|
|
736
|
+
if (opts.copy) {
|
|
737
|
+
await copyToClipboard(beautifiedPath);
|
|
738
|
+
console.log(`[${timestamp()}] \u{1F4CB} Copied to clipboard`);
|
|
739
|
+
}
|
|
690
740
|
if (opts.deleteOriginal) {
|
|
691
741
|
const { unlink } = await import("fs/promises");
|
|
692
742
|
await unlink(filePath);
|
|
@@ -714,7 +764,7 @@ program.command("watch <source> <output>").description("Watch a directory and au
|
|
|
714
764
|
process.exit(1);
|
|
715
765
|
}
|
|
716
766
|
});
|
|
717
|
-
program.command("tray <source> <output>").description("Run as a system tray app with auto-beautify").option("--padding <number>", "Padding around the screenshot", "80").option("--background <path>", "Background image path").option("--preset <name>", "Background preset (run 'presets' to see options)").option("--delete-original", "Delete original file after beautifying", false).option("--foreground", "Run in foreground (don't detach)", false).option("--_daemon", "Internal: running as daemon", false).action(async (source, output, opts) => {
|
|
767
|
+
program.command("tray <source> <output>").description("Run as a system tray app with auto-beautify").option("--padding <number>", "Padding around the screenshot", "80").option("--background <path>", "Background image path").option("--preset <name>", "Background preset (run 'presets' to see options)").option("--delete-original", "Delete original file after beautifying", false).option("--copy", "Copy beautified image to clipboard", false).option("--foreground", "Run in foreground (don't detach)", false).option("--_daemon", "Internal: running as daemon", false).action(async (source, output, opts) => {
|
|
718
768
|
const padding = parseInt(opts.padding, 10);
|
|
719
769
|
const backgroundImage = opts.background ? resolve2(opts.background) : void 0;
|
|
720
770
|
const backgroundPreset = opts.preset;
|
|
@@ -732,6 +782,7 @@ program.command("tray <source> <output>").description("Run as a system tray app
|
|
|
732
782
|
if (backgroundImage) args.push("--background", backgroundImage);
|
|
733
783
|
if (backgroundPreset) args.push("--preset", backgroundPreset);
|
|
734
784
|
if (opts.deleteOriginal) args.push("--delete-original");
|
|
785
|
+
if (opts.copy) args.push("--copy");
|
|
735
786
|
const child = spawn(process.execPath, args, {
|
|
736
787
|
detached: true,
|
|
737
788
|
stdio: "ignore",
|
|
@@ -751,10 +802,11 @@ program.command("tray <source> <output>").description("Run as a system tray app
|
|
|
751
802
|
padding,
|
|
752
803
|
backgroundImage,
|
|
753
804
|
backgroundPreset,
|
|
754
|
-
deleteOriginal: opts.deleteOriginal
|
|
805
|
+
deleteOriginal: opts.deleteOriginal,
|
|
806
|
+
copyToClipboard: opts.copy
|
|
755
807
|
});
|
|
756
808
|
});
|
|
757
|
-
program.command("file <input>", { isDefault: true }).description("Beautify a single screenshot").option("-o, --output <path>", "Output file path").option("--padding <number>", "Padding around the screenshot", "80").option("--background <path>", "Background image path").option("--preset <name>", "Background preset (run 'presets' to see options)").option("--delete-original", "Delete original file after beautifying", false).action(async (input, opts) => {
|
|
809
|
+
program.command("file <input>", { isDefault: true }).description("Beautify a single screenshot").option("-o, --output <path>", "Output file path").option("--padding <number>", "Padding around the screenshot", "80").option("--background <path>", "Background image path").option("--preset <name>", "Background preset (run 'presets' to see options)").option("--delete-original", "Delete original file after beautifying", false).option("--copy", "Copy beautified image to clipboard", false).action(async (input, opts) => {
|
|
758
810
|
try {
|
|
759
811
|
const inputPath = resolve2(input);
|
|
760
812
|
const padding = parseInt(opts.padding || "80", 10);
|
|
@@ -767,6 +819,10 @@ program.command("file <input>", { isDefault: true }).description("Beautify a sin
|
|
|
767
819
|
console.log(`Beautifying: ${inputPath}`);
|
|
768
820
|
await beautify(inputPath, outputPath, { padding, backgroundImage, backgroundPreset });
|
|
769
821
|
console.log(`Saved to: ${outputPath}`);
|
|
822
|
+
if (opts.copy) {
|
|
823
|
+
await copyToClipboard(outputPath);
|
|
824
|
+
console.log(`\u{1F4CB} Copied to clipboard`);
|
|
825
|
+
}
|
|
770
826
|
if (opts.deleteOriginal) {
|
|
771
827
|
const { unlink } = await import("fs/promises");
|
|
772
828
|
await unlink(inputPath);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "screenshot-beautify",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"description": "CLI tool to beautify screenshots with macOS-style window frames and gradient backgrounds",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -23,7 +23,8 @@
|
|
|
23
23
|
"image",
|
|
24
24
|
"frame",
|
|
25
25
|
"macos",
|
|
26
|
-
"gradient"
|
|
26
|
+
"gradient",
|
|
27
|
+
"clipboard"
|
|
27
28
|
],
|
|
28
29
|
"author": "",
|
|
29
30
|
"license": "MIT",
|