pixeli 0.1.9 → 1.0.4

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.
Files changed (212) hide show
  1. package/README.md +362 -88
  2. package/dist/cli/commands/collage/index.d.ts +2 -0
  3. package/dist/cli/commands/collage/index.js +125 -0
  4. package/dist/cli/commands/grid/index.d.ts +2 -0
  5. package/dist/cli/commands/grid/index.js +127 -0
  6. package/dist/cli/commands/masonry/index.d.ts +2 -0
  7. package/dist/cli/commands/masonry/index.js +129 -0
  8. package/dist/cli/commands/template/index.d.ts +2 -0
  9. package/dist/cli/commands/template/index.js +123 -0
  10. package/dist/cli/commands/template/presets/artGallery.d.ts +15 -0
  11. package/dist/cli/commands/template/presets/artGallery.js +15 -0
  12. package/dist/cli/commands/template/presets/dashboardShot.d.ts +15 -0
  13. package/dist/cli/commands/template/presets/dashboardShot.js +16 -0
  14. package/dist/cli/commands/template/presets/horizontalBookSpread.d.ts +15 -0
  15. package/dist/cli/commands/template/presets/horizontalBookSpread.js +13 -0
  16. package/dist/cli/commands/template/presets/instagramGrid.d.ts +15 -0
  17. package/dist/cli/commands/template/presets/instagramGrid.js +16 -0
  18. package/dist/cli/commands/template/presets/verticalBookSpread.d.ts +15 -0
  19. package/dist/cli/commands/template/presets/verticalBookSpread.js +13 -0
  20. package/dist/cli/commands/template/presets.d.ts +73 -0
  21. package/{lib/merges/collage-merge → dist/cli/commands/template}/presets.js +6 -8
  22. package/dist/cli/index.d.ts +2 -0
  23. package/dist/cli/index.js +24 -0
  24. package/dist/cli/modules/loadImages.d.ts +15 -0
  25. package/dist/cli/modules/loadImages.js +74 -0
  26. package/dist/cli/modules/progressBar.d.ts +10 -0
  27. package/dist/cli/modules/progressBar.js +34 -0
  28. package/dist/cli/schemas/collage.d.ts +29 -0
  29. package/dist/cli/schemas/collage.js +38 -0
  30. package/dist/cli/schemas/grid.d.ts +34 -0
  31. package/dist/cli/schemas/grid.js +38 -0
  32. package/dist/cli/schemas/masonry.d.ts +62 -0
  33. package/dist/cli/schemas/masonry.js +62 -0
  34. package/dist/cli/schemas/template.d.ts +31 -0
  35. package/dist/cli/schemas/template.js +49 -0
  36. package/dist/cli/utils/buildCommandFromSchema.d.ts +8 -0
  37. package/dist/cli/utils/buildCommandFromSchema.js +55 -0
  38. package/dist/cli/utils/configureCommandErrors.d.ts +2 -0
  39. package/dist/cli/utils/configureCommandErrors.js +22 -0
  40. package/dist/cli/utils/stringFormatter.d.ts +1 -0
  41. package/dist/cli/utils/stringFormatter.js +3 -0
  42. package/dist/cli/utils/toErrorMessage.d.ts +4 -0
  43. package/dist/cli/utils/toErrorMessage.js +22 -0
  44. package/dist/core/helpers.d.ts +10 -0
  45. package/dist/core/helpers.js +42 -0
  46. package/dist/core/index.d.ts +2 -0
  47. package/dist/core/index.js +2 -0
  48. package/dist/core/jobs/batchRunner.d.ts +44 -0
  49. package/dist/core/jobs/batchRunner.js +90 -0
  50. package/dist/core/jobs/types.d.ts +10 -0
  51. package/dist/core/jobs/types.js +1 -0
  52. package/dist/core/mergeError.d.ts +9 -0
  53. package/dist/core/mergeError.js +10 -0
  54. package/dist/core/merges/collage/index.d.ts +9 -0
  55. package/dist/core/merges/collage/index.js +32 -0
  56. package/dist/core/merges/collage/steps/calculateImageDimensions.d.ts +12 -0
  57. package/dist/core/merges/collage/steps/calculateImageDimensions.js +18 -0
  58. package/dist/core/merges/collage/steps/createComposites.d.ts +8 -0
  59. package/dist/core/merges/collage/steps/createComposites.js +58 -0
  60. package/dist/core/merges/collage/steps/resizeAndBorderImages.d.ts +12 -0
  61. package/dist/core/merges/collage/steps/resizeAndBorderImages.js +26 -0
  62. package/dist/core/merges/collage/steps/rotateImages.d.ts +7 -0
  63. package/dist/core/merges/collage/steps/rotateImages.js +9 -0
  64. package/dist/core/merges/grid/index.d.ts +12 -0
  65. package/dist/core/merges/grid/index.js +36 -0
  66. package/dist/core/merges/grid/steps/calculateCanvasDimensions.d.ts +8 -0
  67. package/dist/core/merges/grid/steps/calculateCanvasDimensions.js +18 -0
  68. package/dist/core/merges/grid/steps/calculateFontSize.d.ts +7 -0
  69. package/dist/core/merges/grid/steps/calculateFontSize.js +19 -0
  70. package/dist/core/merges/grid/steps/calculateImageDimensions.d.ts +8 -0
  71. package/dist/core/merges/grid/steps/calculateImageDimensions.js +18 -0
  72. package/dist/core/merges/grid/steps/createComposites.d.ts +10 -0
  73. package/dist/core/merges/grid/steps/createComposites.js +63 -0
  74. package/dist/core/merges/grid/steps/prepareImages.d.ts +10 -0
  75. package/dist/core/merges/grid/steps/prepareImages.js +29 -0
  76. package/dist/core/merges/grid/steps/shuffleImagesAndCaptions.d.ts +7 -0
  77. package/dist/core/merges/grid/steps/shuffleImagesAndCaptions.js +17 -0
  78. package/dist/core/merges/index.d.ts +5 -0
  79. package/dist/core/merges/index.js +4 -0
  80. package/dist/core/merges/masonry/index.d.ts +10 -0
  81. package/dist/core/merges/masonry/index.js +32 -0
  82. package/dist/core/merges/masonry/steps/calculateCanvasDimensions.d.ts +15 -0
  83. package/dist/core/merges/masonry/steps/calculateCanvasDimensions.js +17 -0
  84. package/dist/core/merges/masonry/steps/calculateLaneSize.d.ts +9 -0
  85. package/dist/core/merges/masonry/steps/calculateLaneSize.js +27 -0
  86. package/dist/core/merges/masonry/steps/createComposites.d.ts +25 -0
  87. package/dist/core/merges/masonry/steps/createComposites.js +108 -0
  88. package/dist/core/merges/masonry/steps/resizeImages.d.ts +7 -0
  89. package/dist/core/merges/masonry/steps/resizeImages.js +14 -0
  90. package/dist/core/merges/masonry/steps/splitIntoLanes.d.ts +17 -0
  91. package/dist/core/merges/masonry/steps/splitIntoLanes.js +78 -0
  92. package/dist/core/merges/shared-steps/applyComposites.d.ts +2 -0
  93. package/dist/core/merges/shared-steps/applyComposites.js +16 -0
  94. package/dist/core/merges/shared-steps/createCanvas.d.ts +11 -0
  95. package/dist/core/merges/shared-steps/createCanvas.js +17 -0
  96. package/dist/core/merges/shared-steps/exportCanvas.d.ts +7 -0
  97. package/dist/core/merges/shared-steps/exportCanvas.js +25 -0
  98. package/dist/core/merges/shared-steps/finalizeImagePipelines.d.ts +2 -0
  99. package/dist/core/merges/shared-steps/finalizeImagePipelines.js +9 -0
  100. package/dist/core/merges/shared-steps/loadImages.d.ts +2 -0
  101. package/dist/core/merges/shared-steps/loadImages.js +26 -0
  102. package/dist/core/merges/shared-steps/validateCaptions.d.ts +10 -0
  103. package/dist/core/merges/shared-steps/validateCaptions.js +17 -0
  104. package/dist/core/merges/template/index.d.ts +10 -0
  105. package/dist/core/merges/template/index.js +28 -0
  106. package/dist/core/merges/template/steps/calculateSlotDimensions.d.ts +9 -0
  107. package/dist/core/merges/template/steps/calculateSlotDimensions.js +12 -0
  108. package/dist/core/merges/template/steps/createComposites.d.ts +10 -0
  109. package/dist/core/merges/template/steps/createComposites.js +25 -0
  110. package/dist/core/merges/template/steps/getBlocks.d.ts +13 -0
  111. package/dist/core/merges/template/steps/getBlocks.js +28 -0
  112. package/dist/core/merges/template/types.d.ts +21 -0
  113. package/dist/core/merges/template/types.js +1 -0
  114. package/dist/core/merges/types.d.ts +123 -0
  115. package/dist/core/merges/types.js +1 -0
  116. package/dist/core/modules/messages.d.ts +32 -0
  117. package/dist/core/modules/messages.js +54 -0
  118. package/dist/core/modules/typedEventEmitter.d.ts +7 -0
  119. package/dist/core/modules/typedEventEmitter.js +9 -0
  120. package/dist/core/pipeline/guards.d.ts +4 -0
  121. package/dist/core/pipeline/guards.js +23 -0
  122. package/dist/core/pipeline/mergePipeline.d.ts +60 -0
  123. package/dist/core/pipeline/mergePipeline.js +122 -0
  124. package/dist/core/schemas/collage.d.ts +26 -0
  125. package/dist/core/schemas/collage.js +17 -0
  126. package/dist/core/schemas/grid.d.ts +32 -0
  127. package/dist/core/schemas/grid.js +29 -0
  128. package/dist/core/schemas/masonry.d.ts +56 -0
  129. package/dist/core/schemas/masonry.js +43 -0
  130. package/dist/core/schemas/mergeJob.d.ts +11 -0
  131. package/dist/core/schemas/mergeJob.js +6 -0
  132. package/dist/core/schemas/template.d.ts +34 -0
  133. package/dist/core/schemas/template.js +88 -0
  134. package/dist/core/utils/colors/hexToRgba.d.ts +2 -0
  135. package/dist/core/utils/colors/hexToRgba.js +25 -0
  136. package/dist/core/utils/colors/rgbaToHex.d.ts +2 -0
  137. package/dist/core/utils/colors/rgbaToHex.js +15 -0
  138. package/dist/core/utils/colors/types.d.ts +7 -0
  139. package/dist/core/utils/colors/types.js +1 -0
  140. package/dist/core/utils/fonts/getFontSize.d.ts +9 -0
  141. package/dist/core/utils/fonts/getFontSize.js +40 -0
  142. package/dist/core/utils/images/addImageBorder.d.ts +13 -0
  143. package/dist/core/utils/images/addImageBorder.js +33 -0
  144. package/dist/core/utils/images/getImageHeights.d.ts +2 -0
  145. package/dist/core/utils/images/getImageHeights.js +9 -0
  146. package/dist/core/utils/images/getImageWidths.d.ts +2 -0
  147. package/dist/core/utils/images/getImageWidths.js +9 -0
  148. package/dist/core/utils/images/getSmallestImageDimensions.d.ts +5 -0
  149. package/dist/core/utils/images/getSmallestImageDimensions.js +9 -0
  150. package/dist/core/utils/images/handleImageEdges.d.ts +13 -0
  151. package/dist/core/utils/images/handleImageEdges.js +39 -0
  152. package/dist/core/utils/images/isActualImage.d.ts +5 -0
  153. package/dist/core/utils/images/isActualImage.js +26 -0
  154. package/dist/core/utils/images/parseAspectRatio.d.ts +1 -0
  155. package/dist/core/utils/images/parseAspectRatio.js +22 -0
  156. package/dist/core/utils/images/roundImage.d.ts +9 -0
  157. package/dist/core/utils/images/roundImage.js +27 -0
  158. package/dist/core/utils/images/roundImages.d.ts +8 -0
  159. package/dist/core/utils/images/roundImages.js +19 -0
  160. package/dist/core/utils/images/scaleImage.d.ts +8 -0
  161. package/dist/core/utils/images/scaleImage.js +36 -0
  162. package/dist/core/utils/images/scaleImages.d.ts +8 -0
  163. package/dist/core/utils/images/scaleImages.js +38 -0
  164. package/dist/core/utils/math/median.d.ts +1 -0
  165. package/dist/core/utils/math/median.js +12 -0
  166. package/dist/core/utils/math/randint.d.ts +6 -0
  167. package/dist/core/utils/math/randint.js +11 -0
  168. package/dist/core/utils/math/trimmedMedian.d.ts +1 -0
  169. package/dist/core/utils/math/trimmedMedian.js +12 -0
  170. package/dist/core/utils/svg/createSvgTextBuffer.d.ts +9 -0
  171. package/dist/core/utils/svg/createSvgTextBuffer.js +21 -0
  172. package/dist/validators/aspectRatio.d.ts +2 -0
  173. package/dist/validators/aspectRatio.js +15 -0
  174. package/dist/validators/coercion.d.ts +2 -0
  175. package/dist/validators/coercion.js +12 -0
  176. package/dist/validators/format.d.ts +2 -0
  177. package/dist/validators/format.js +15 -0
  178. package/dist/validators/hexColor.d.ts +7 -0
  179. package/dist/validators/hexColor.js +27 -0
  180. package/dist/validators/index.d.ts +95 -0
  181. package/dist/validators/index.js +64 -0
  182. package/dist/validators/outputFile.d.ts +2 -0
  183. package/dist/validators/outputFile.js +7 -0
  184. package/dist/validators/path.d.ts +3 -0
  185. package/dist/validators/path.js +18 -0
  186. package/dist/validators/sharpImageInput.d.ts +3 -0
  187. package/dist/validators/sharpImageInput.js +6 -0
  188. package/dist/validators/template.d.ts +15 -0
  189. package/dist/validators/template.js +41 -0
  190. package/package.json +26 -9
  191. package/bin/pixeli.js +0 -26
  192. package/commands/merge/collage.js +0 -83
  193. package/commands/merge/grid.js +0 -71
  194. package/commands/merge/helpers/utils.js +0 -11
  195. package/commands/merge/helpers/validations.js +0 -269
  196. package/commands/merge/index.js +0 -12
  197. package/commands/merge/masonry.js +0 -72
  198. package/lib/helpers/loadImages.js +0 -94
  199. package/lib/helpers/progressBar.js +0 -20
  200. package/lib/helpers/templateValidator.js +0 -139
  201. package/lib/helpers/utils.js +0 -208
  202. package/lib/merges/collage-merge/index.js +0 -110
  203. package/lib/merges/collage-merge/presets/artGallery.js +0 -17
  204. package/lib/merges/collage-merge/presets/dashboardShot.js +0 -18
  205. package/lib/merges/collage-merge/presets/horizontalBookSpread.js +0 -15
  206. package/lib/merges/collage-merge/presets/instagramGrid.js +0 -18
  207. package/lib/merges/collage-merge/presets/verticalBookSpread.js +0 -15
  208. package/lib/merges/grid-merge/index.js +0 -152
  209. package/lib/merges/masonry-merge/horizontal.js +0 -157
  210. package/lib/merges/masonry-merge/index.js +0 -57
  211. package/lib/merges/masonry-merge/vertical.js +0 -152
  212. package/lib/merges/merge-utils.js +0 -176
@@ -0,0 +1,125 @@
1
+ import path from 'node:path';
2
+ import fs from 'node:fs/promises';
3
+ import { buildCommandFromSchema } from '../../utils/buildCommandFromSchema.js';
4
+ import { collageMerge } from '../../../core/merges/collage/index.js';
5
+ import { loadImages } from '../../modules/loadImages.js';
6
+ import { MergeProgressBar } from '../../modules/progressBar.js';
7
+ import { MessageRenderer, MESSAGES } from '../../../core/modules/messages.js';
8
+ import { toErrorMessage } from '../../utils/toErrorMessage.js';
9
+ import { cliCollageSchema } from '../../schemas/collage.js';
10
+ const collageCommand = buildCommandFromSchema('collage', 'Arranges images in a messy, photo wall style grid.', cliCollageSchema, {
11
+ files: {
12
+ flags: '[files...]',
13
+ description: 'Image filepaths to merge (use --dir for directories)',
14
+ },
15
+ }, {
16
+ dir: {
17
+ flags: '-d, --dir <path>',
18
+ description: 'Directory of images to merge',
19
+ },
20
+ recursive: {
21
+ flags: '-r, --recursive',
22
+ description: 'Recursively include subdirectories',
23
+ },
24
+ shuffle: {
25
+ flags: '--sh, --shuffle',
26
+ description: 'Shuffle up images to randomize order in the grid',
27
+ },
28
+ cornerRadius: {
29
+ flags: '--cr, --corner-radius <px>',
30
+ description: 'How much to round the corners of each image',
31
+ },
32
+ gap: {
33
+ flags: '-g, --gap <px>',
34
+ description: 'Gap between images',
35
+ },
36
+ canvasColor: {
37
+ flags: '--bg, --canvas-color <hex|transparent>',
38
+ description: 'Background color for canvas',
39
+ },
40
+ borderWidth: {
41
+ flags: '--bw, --border-width <px>',
42
+ description: 'Width of the border around each image. Borders are placed internally in each image',
43
+ },
44
+ borderColor: {
45
+ flags: '--bc, --border-color <hex>',
46
+ description: 'Color of the border around each image',
47
+ },
48
+ output: {
49
+ flags: '-o, --output <file>',
50
+ description: 'Output file path',
51
+ },
52
+ aspectRatio: {
53
+ flags: '--ar, --aspect-ratio <width/height|number>',
54
+ description: 'The aspect ratio of all the images (examples: 16/9, 4:3, 1.777)',
55
+ },
56
+ imageWidth: {
57
+ flags: '-w, --image-width <px>',
58
+ description: 'The width of each image, defaults to the smallest image',
59
+ },
60
+ columns: {
61
+ flags: '-c, --columns <n>',
62
+ description: 'The number of columns',
63
+ },
64
+ overlapPercentage: {
65
+ flags: '--op, --overlap-percentage <percent>',
66
+ description: 'The estimated percentage of overlap for every image pair. A higher percentage creates a tighter collage',
67
+ },
68
+ rotationRange: {
69
+ flags: '--rr, --rotation-range <deg>',
70
+ description: 'The maximum and minimum degrees to randomly rotate each image',
71
+ },
72
+ imageWidthVariance: {
73
+ flags: '--wv, --image-width-variance <px>',
74
+ description: 'The number of pixels to potentially variate imageWidth by. Used to create random-sized images in the collage',
75
+ },
76
+ }).action(async (files, opts) => {
77
+ const input = { files, ...opts };
78
+ // Use progress bar module to track progress
79
+ const bar = new MergeProgressBar();
80
+ try {
81
+ const validatedOptions = await cliCollageSchema.parseAsync(input);
82
+ // Use load images module
83
+ const { images, ignoredPaths } = await loadImages({
84
+ input: { files: validatedOptions.files, dir: validatedOptions.dir },
85
+ recursive: validatedOptions.recursive,
86
+ });
87
+ // Ensure user knows about ignored files
88
+ if (ignoredPaths.length) {
89
+ const warning = new MessageRenderer(MESSAGES.WARNINGS.IGNORED_FILES, ignoredPaths.join('\n') + '\n');
90
+ const confirmation = await warning.confirm();
91
+ if (!confirmation)
92
+ return;
93
+ }
94
+ // Collect merge options
95
+ const { recursive, output, files, dir, ...cliOptions } = validatedOptions;
96
+ const format = path.extname(output).replace('.', '');
97
+ const mergeOptions = {
98
+ format,
99
+ ...cliOptions,
100
+ };
101
+ // Get grid buffer
102
+ const buffer = await collageMerge(images, mergeOptions, (progressInfo) => {
103
+ if (!bar.progressBar.isActive) {
104
+ bar.startBar(progressInfo.phase);
105
+ }
106
+ else {
107
+ bar.updateBar(progressInfo);
108
+ }
109
+ });
110
+ // Write file and display success message
111
+ await fs.writeFile(output, buffer);
112
+ bar.endBar();
113
+ const success = new MessageRenderer(MESSAGES.SUCCESS.OUTPUT, output);
114
+ success.render();
115
+ }
116
+ catch (err) {
117
+ // End the progress bar
118
+ bar.endBar();
119
+ // Create and render error
120
+ const errorMessage = toErrorMessage(err);
121
+ const error = new MessageRenderer(errorMessage);
122
+ error.render();
123
+ }
124
+ });
125
+ export default collageCommand;
@@ -0,0 +1,2 @@
1
+ declare const gridCommand: import("commander").Command;
2
+ export default gridCommand;
@@ -0,0 +1,127 @@
1
+ import path from 'node:path';
2
+ import fs from 'node:fs/promises';
3
+ import { buildCommandFromSchema } from '../../utils/buildCommandFromSchema.js';
4
+ import { gridMerge } from '../../../core/merges/grid/index.js';
5
+ import { cliGridSchema } from '../../schemas/grid.js';
6
+ import { loadImages } from '../../modules/loadImages.js';
7
+ import { MergeProgressBar } from '../../modules/progressBar.js';
8
+ import { MessageRenderer, MESSAGES } from '../../../core/modules/messages.js';
9
+ import { toErrorMessage } from '../../utils/toErrorMessage.js';
10
+ const gridCommand = buildCommandFromSchema('grid', 'Arranges images in an organized grid.', cliGridSchema, {
11
+ files: {
12
+ flags: '[files...]',
13
+ description: 'Image filepaths to merge (use --dir for directories)',
14
+ },
15
+ }, {
16
+ dir: {
17
+ flags: '-d, --dir <path>',
18
+ description: 'Directory of images to merge',
19
+ },
20
+ recursive: {
21
+ flags: '-r, --recursive',
22
+ description: 'Recursively include subdirectories',
23
+ },
24
+ shuffle: {
25
+ flags: '--sh, --shuffle',
26
+ description: 'Shuffle up images to randomize order in the grid',
27
+ },
28
+ cornerRadius: {
29
+ flags: '--cr, --corner-radius <px>',
30
+ description: 'How much to round the corners of each image',
31
+ },
32
+ gap: {
33
+ flags: '-g, --gap <px>',
34
+ description: 'Gap between images',
35
+ },
36
+ canvasColor: {
37
+ flags: '--bg, --canvas-color <hex|transparent>',
38
+ description: 'Background color for canvas',
39
+ },
40
+ borderWidth: {
41
+ flags: '--bw, --border-width <px>',
42
+ description: 'Width of the border around each image. Borders are placed internally in each image',
43
+ },
44
+ borderColor: {
45
+ flags: '--bc, --border-color <hex>',
46
+ description: 'Color of the border around each image',
47
+ },
48
+ output: {
49
+ flags: '-o, --output <file>',
50
+ description: 'Output file path',
51
+ },
52
+ aspectRatio: {
53
+ flags: '--ar, --aspect-ratio <width/height|number>',
54
+ description: 'The aspect ratio of all the images (examples: 16/9, 4:3, 1.777)',
55
+ },
56
+ imageWidth: {
57
+ flags: '-w, --image-width <px>',
58
+ description: 'The width of each image, defaults to the smallest image',
59
+ },
60
+ columns: {
61
+ flags: '-c, --columns <n>',
62
+ description: 'The number of columns',
63
+ },
64
+ caption: {
65
+ flags: '--ca, --caption',
66
+ description: 'Whether to caption each image',
67
+ },
68
+ captionColor: {
69
+ flags: '--cc, --caption-color <hex>',
70
+ description: 'Image caption color',
71
+ },
72
+ maxCaptionSize: {
73
+ flags: '--mcs, --max-caption-size <pt>',
74
+ description: 'The maximum allowed caption size',
75
+ },
76
+ }).action(async (files, opts) => {
77
+ const input = { files, ...opts };
78
+ // Use progress bar module to track progress
79
+ const bar = new MergeProgressBar();
80
+ try {
81
+ const validatedOptions = await cliGridSchema.parseAsync(input);
82
+ // Use load images module
83
+ const { images, imagePaths, ignoredPaths } = await loadImages({
84
+ input: { files: validatedOptions.files, dir: validatedOptions.dir },
85
+ recursive: validatedOptions.recursive,
86
+ });
87
+ // Ensure user knows about ignored files
88
+ if (ignoredPaths.length) {
89
+ const warning = new MessageRenderer(MESSAGES.WARNINGS.IGNORED_FILES, ignoredPaths.join('\n') + '\n');
90
+ const confirmation = await warning.confirm();
91
+ if (!confirmation)
92
+ return;
93
+ }
94
+ // Collect merge options
95
+ const { recursive, output, files, dir, ...cliOptions } = validatedOptions;
96
+ const format = path.extname(output).replace('.', '');
97
+ const captions = imagePaths.map((p) => path.basename(p));
98
+ const mergeOptions = {
99
+ format,
100
+ captions,
101
+ ...cliOptions,
102
+ };
103
+ // Get grid buffer
104
+ const buffer = await gridMerge(images, mergeOptions, (progressInfo) => {
105
+ if (!bar.progressBar.isActive) {
106
+ bar.startBar(progressInfo.phase);
107
+ }
108
+ else {
109
+ bar.updateBar(progressInfo);
110
+ }
111
+ });
112
+ // Write file and display success message
113
+ await fs.writeFile(output, buffer);
114
+ bar.endBar();
115
+ const success = new MessageRenderer(MESSAGES.SUCCESS.OUTPUT, output);
116
+ success.render();
117
+ }
118
+ catch (err) {
119
+ // End the progress bar
120
+ bar.endBar();
121
+ // Create and render error
122
+ const errorMessage = toErrorMessage(err);
123
+ const error = new MessageRenderer(errorMessage);
124
+ error.render();
125
+ }
126
+ });
127
+ export default gridCommand;
@@ -0,0 +1,2 @@
1
+ declare const masonryCommand: import("commander").Command;
2
+ export default masonryCommand;
@@ -0,0 +1,129 @@
1
+ import path from 'node:path';
2
+ import fs from 'node:fs/promises';
3
+ import { buildCommandFromSchema } from '../../utils/buildCommandFromSchema.js';
4
+ import { masonryMerge } from '../../../core/merges/masonry/index.js';
5
+ import { cliMasonrySchema } from '../../schemas/masonry.js';
6
+ import { loadImages } from '../../modules/loadImages.js';
7
+ import { MergeProgressBar } from '../../modules/progressBar.js';
8
+ import { MessageRenderer, MESSAGES } from '../../../core/modules/messages.js';
9
+ import { toErrorMessage } from '../../utils/toErrorMessage.js';
10
+ const masonryCommand = buildCommandFromSchema('masonry', "Use a ragged-grid layout, preserves images' aspect ratios", cliMasonrySchema, {
11
+ files: {
12
+ flags: '[files...]',
13
+ description: 'Image filepaths to merge (use --dir for directories)',
14
+ },
15
+ }, {
16
+ dir: {
17
+ flags: '-d, --dir <path>',
18
+ description: 'Directory of images to merge',
19
+ },
20
+ recursive: {
21
+ flags: '-r, --recursive',
22
+ description: 'Recursively include subdirectories',
23
+ },
24
+ shuffle: {
25
+ flags: '--sh, --shuffle',
26
+ description: 'Shuffle up images to randomize order in the grid',
27
+ },
28
+ cornerRadius: {
29
+ flags: '--cr, --corner-radius <px>',
30
+ description: 'How much to round the corners of each image',
31
+ },
32
+ gap: {
33
+ flags: '-g, --gap <px>',
34
+ description: 'Gap between images',
35
+ },
36
+ canvasColor: {
37
+ flags: '--bg, --canvas-color <hex|transparent>',
38
+ description: 'Background color for canvas',
39
+ },
40
+ borderWidth: {
41
+ flags: '--bw, --border-width <px>',
42
+ description: 'Width of the border around each image. Borders are placed internally in each image',
43
+ },
44
+ borderColor: {
45
+ flags: '--bc, --border-color <hex>',
46
+ description: 'Color of the border around each image',
47
+ },
48
+ output: {
49
+ flags: '-o, --output <file>',
50
+ description: 'Output file path',
51
+ },
52
+ rowHeight: {
53
+ flags: '--rh, --row-height <px>',
54
+ description: 'The height of each row, defaults to the trimmed median image height if undefined. Only applied in horizontal flows.',
55
+ },
56
+ columnWidth: {
57
+ flags: '--cw, --column-width <px>',
58
+ description: 'The width of each column, defaults to the trimmed median image width if undefined. Only applied in vertical flows.',
59
+ },
60
+ canvasWidth: {
61
+ flags: '--cvw, --canvas-width <px>',
62
+ description: 'The width of the entire canvas. Only required in horizontal flows.',
63
+ },
64
+ canvasHeight: {
65
+ flags: '--cvh, --canvas-height <px>',
66
+ description: 'The width of the entire canvas. Only required in vertical flows.',
67
+ },
68
+ flow: {
69
+ flags: '-f, --flow <horizontal|vertical>',
70
+ description: 'The orientation of the masonry layout.',
71
+ },
72
+ hAlign: {
73
+ flags: '--ha, --h-align <left|center|right|justified>',
74
+ description: 'The horizontal alignment of each row. Only applied in horizontal layouts.',
75
+ },
76
+ vAlign: {
77
+ flags: '--va, --v-align <top|middle|bottom|justified>',
78
+ description: 'The vertical alignment of each column. Only applied in vertical layouts.',
79
+ },
80
+ }).action(async (files, opts) => {
81
+ const input = { files, ...opts };
82
+ // Use progress bar module to track progress
83
+ const bar = new MergeProgressBar();
84
+ try {
85
+ const validatedOptions = await cliMasonrySchema.parseAsync(input);
86
+ // Use load images module
87
+ const { images, ignoredPaths } = await loadImages({
88
+ input: { files: validatedOptions.files, dir: validatedOptions.dir },
89
+ recursive: validatedOptions.recursive,
90
+ });
91
+ // Ensure user knows about ignored files
92
+ if (ignoredPaths.length) {
93
+ const warning = new MessageRenderer(MESSAGES.WARNINGS.IGNORED_FILES, ignoredPaths.join('\n') + '\n');
94
+ const confirmation = await warning.confirm();
95
+ if (!confirmation)
96
+ return;
97
+ }
98
+ // Collect merge options
99
+ const { recursive, output, files, dir, ...cliOptions } = validatedOptions;
100
+ const format = path.extname(output).replace('.', '');
101
+ let mergeOptions = {
102
+ format,
103
+ ...cliOptions,
104
+ };
105
+ // Get grid buffer
106
+ const buffer = await masonryMerge(images, mergeOptions, (progressInfo) => {
107
+ if (!bar.progressBar.isActive) {
108
+ bar.startBar(progressInfo.phase);
109
+ }
110
+ else {
111
+ bar.updateBar(progressInfo);
112
+ }
113
+ });
114
+ // Write file and display success message
115
+ await fs.writeFile(output, buffer);
116
+ bar.endBar();
117
+ const success = new MessageRenderer(MESSAGES.SUCCESS.OUTPUT, output);
118
+ success.render();
119
+ }
120
+ catch (err) {
121
+ // End the progress bar
122
+ bar.endBar();
123
+ // Create and render error
124
+ const errorMessage = toErrorMessage(err);
125
+ const error = new MessageRenderer(errorMessage);
126
+ error.render();
127
+ }
128
+ });
129
+ export default masonryCommand;
@@ -0,0 +1,2 @@
1
+ declare const templateCommand: import("commander").Command;
2
+ export default templateCommand;
@@ -0,0 +1,123 @@
1
+ import path from 'node:path';
2
+ import fs, { readFile } from 'node:fs/promises';
3
+ import { buildCommandFromSchema } from '../../utils/buildCommandFromSchema.js';
4
+ import { templateMerge } from '../../../core/merges/template/index.js';
5
+ import { cliTemplateSchema } from '../../schemas/template.js';
6
+ import { PRESETS } from './presets.js';
7
+ import { loadImages } from '../../modules/loadImages.js';
8
+ import { MergeProgressBar } from '../../modules/progressBar.js';
9
+ import { MessageRenderer, MESSAGES } from '../../../core/modules/messages.js';
10
+ import { toErrorMessage } from '../../utils/toErrorMessage.js';
11
+ const templateCommand = buildCommandFromSchema('template', 'Use JSON layouts to build custom collages', cliTemplateSchema, {
12
+ files: {
13
+ flags: '[files...]',
14
+ description: 'Image filepaths to merge (use --dir for directories)',
15
+ },
16
+ }, {
17
+ dir: {
18
+ flags: '-d, --dir <path>',
19
+ description: 'Directory of images to merge',
20
+ },
21
+ recursive: {
22
+ flags: '-r, --recursive',
23
+ description: 'Recursively include subdirectories',
24
+ },
25
+ shuffle: {
26
+ flags: '--sh, --shuffle',
27
+ description: 'Shuffle up images to randomize order in the grid',
28
+ },
29
+ cornerRadius: {
30
+ flags: '--cr, --corner-radius <px>',
31
+ description: 'How much to round the corners of each image',
32
+ },
33
+ gap: {
34
+ flags: '-g, --gap <px>',
35
+ description: 'Gap between images',
36
+ },
37
+ canvasColor: {
38
+ flags: '--bg, --canvas-color <hex|transparent>',
39
+ description: 'Background color for canvas',
40
+ },
41
+ borderWidth: {
42
+ flags: '--bw, --border-width <px>',
43
+ description: 'Width of the border around each image. Borders are placed internally in each image',
44
+ },
45
+ borderColor: {
46
+ flags: '--bc, --border-color <hex>',
47
+ description: 'Color of the border around each image',
48
+ },
49
+ output: {
50
+ flags: '-o, --output <file>',
51
+ description: 'Output file path',
52
+ },
53
+ template: {
54
+ flags: '-t, --template <path>',
55
+ description: 'The path to the JSON file describing the template',
56
+ },
57
+ preset: {
58
+ flags: '-p, --preset <preset-id>',
59
+ description: `Template preset ID to use. Available collage IDs: ${Object.keys(PRESETS).join(', ')}`,
60
+ },
61
+ }).action(async (files, opts) => {
62
+ const input = { files, ...opts };
63
+ // Use progress bar module to track progress
64
+ const bar = new MergeProgressBar();
65
+ try {
66
+ const validatedOptions = await cliTemplateSchema.parseAsync(input);
67
+ // Use load images module
68
+ const { images, ignoredPaths } = await loadImages({
69
+ input: { files: validatedOptions.files, dir: validatedOptions.dir },
70
+ recursive: validatedOptions.recursive,
71
+ });
72
+ // Ensure user knows about ignored files
73
+ if (ignoredPaths.length) {
74
+ const warning = new MessageRenderer(MESSAGES.WARNINGS.IGNORED_FILES, ignoredPaths.join('\n') + '\n');
75
+ const confirmation = await warning.confirm();
76
+ if (!confirmation)
77
+ return;
78
+ }
79
+ // Collect merge options
80
+ const { recursive, output, files, dir, template, preset, ...cliOptions } = validatedOptions;
81
+ // Get the template file
82
+ let templateObj;
83
+ if (validatedOptions.template !== undefined) {
84
+ const templateJson = await readFile(validatedOptions.template, 'utf-8');
85
+ templateObj = JSON.parse(templateJson);
86
+ }
87
+ else if (validatedOptions.preset !== undefined) {
88
+ templateObj = PRESETS[validatedOptions.preset];
89
+ }
90
+ else {
91
+ throw new Error(MESSAGES.ERROR.INTERNAL.message);
92
+ }
93
+ const format = path.extname(output).replace('.', '');
94
+ let mergeOptions = {
95
+ format,
96
+ template: templateObj,
97
+ ...cliOptions,
98
+ };
99
+ // Get grid buffer
100
+ const buffer = await templateMerge(images, mergeOptions, (progressInfo) => {
101
+ if (!bar.progressBar.isActive) {
102
+ bar.startBar(progressInfo.phase);
103
+ }
104
+ else {
105
+ bar.updateBar(progressInfo);
106
+ }
107
+ });
108
+ // Write file and display success message
109
+ await fs.writeFile(output, buffer);
110
+ bar.endBar();
111
+ const success = new MessageRenderer(MESSAGES.SUCCESS.OUTPUT, output);
112
+ success.render();
113
+ }
114
+ catch (err) {
115
+ // End the progress bar
116
+ bar.endBar();
117
+ // Create and render error
118
+ const errorMessage = toErrorMessage(err);
119
+ const error = new MessageRenderer(errorMessage);
120
+ error.render();
121
+ }
122
+ });
123
+ export default templateCommand;
@@ -0,0 +1,15 @@
1
+ declare const _default: {
2
+ canvas: {
3
+ width: number;
4
+ height: number;
5
+ columns: number;
6
+ rows: number;
7
+ };
8
+ slots: {
9
+ col: number;
10
+ row: number;
11
+ colSpan: number;
12
+ rowSpan: number;
13
+ }[];
14
+ };
15
+ export default _default;
@@ -0,0 +1,15 @@
1
+ export default {
2
+ canvas: {
3
+ width: 4000,
4
+ height: 3000,
5
+ columns: 5,
6
+ rows: 5,
7
+ },
8
+ slots: [
9
+ { col: 1, row: 1, colSpan: 3, rowSpan: 3 },
10
+ { col: 4, row: 1, colSpan: 2, rowSpan: 2 },
11
+ { col: 4, row: 3, colSpan: 2, rowSpan: 1 },
12
+ { col: 1, row: 4, colSpan: 2, rowSpan: 2 },
13
+ { col: 3, row: 4, colSpan: 3, rowSpan: 2 },
14
+ ],
15
+ };
@@ -0,0 +1,15 @@
1
+ declare const _default: {
2
+ canvas: {
3
+ width: number;
4
+ height: number;
5
+ columns: number;
6
+ rows: number;
7
+ };
8
+ slots: {
9
+ col: number;
10
+ row: number;
11
+ colSpan: number;
12
+ rowSpan: number;
13
+ }[];
14
+ };
15
+ export default _default;
@@ -0,0 +1,16 @@
1
+ export default {
2
+ canvas: {
3
+ width: 3600,
4
+ height: 2400,
5
+ columns: 6,
6
+ rows: 4,
7
+ },
8
+ slots: [
9
+ { col: 1, row: 1, colSpan: 3, rowSpan: 2 },
10
+ { col: 4, row: 1, colSpan: 3, rowSpan: 1 },
11
+ { col: 4, row: 2, colSpan: 3, rowSpan: 1 },
12
+ { col: 1, row: 3, colSpan: 2, rowSpan: 2 },
13
+ { col: 3, row: 3, colSpan: 2, rowSpan: 2 },
14
+ { col: 5, row: 3, colSpan: 2, rowSpan: 2 },
15
+ ],
16
+ };
@@ -0,0 +1,15 @@
1
+ declare const _default: {
2
+ canvas: {
3
+ width: number;
4
+ height: number;
5
+ columns: number;
6
+ rows: number;
7
+ };
8
+ slots: {
9
+ col: number;
10
+ row: number;
11
+ colSpan: number;
12
+ rowSpan: number;
13
+ }[];
14
+ };
15
+ export default _default;
@@ -0,0 +1,13 @@
1
+ export default {
2
+ canvas: {
3
+ width: 4800,
4
+ height: 2800,
5
+ columns: 8,
6
+ rows: 3,
7
+ },
8
+ slots: [
9
+ { col: 1, row: 1, colSpan: 3, rowSpan: 3 },
10
+ { col: 4, row: 1, colSpan: 5, rowSpan: 1 },
11
+ { col: 4, row: 2, colSpan: 5, rowSpan: 2 },
12
+ ],
13
+ };
@@ -0,0 +1,15 @@
1
+ declare const _default: {
2
+ canvas: {
3
+ width: number;
4
+ height: number;
5
+ columns: number;
6
+ rows: number;
7
+ };
8
+ slots: {
9
+ col: number;
10
+ row: number;
11
+ colSpan: number;
12
+ rowSpan: number;
13
+ }[];
14
+ };
15
+ export default _default;
@@ -0,0 +1,16 @@
1
+ export default {
2
+ canvas: {
3
+ width: 2400,
4
+ height: 3200,
5
+ columns: 3,
6
+ rows: 6,
7
+ },
8
+ slots: [
9
+ { col: 1, row: 1, colSpan: 2, rowSpan: 2 },
10
+ { col: 3, row: 1, colSpan: 1, rowSpan: 1 },
11
+ { col: 3, row: 2, colSpan: 1, rowSpan: 1 },
12
+ { col: 1, row: 3, colSpan: 1, rowSpan: 2 },
13
+ { col: 2, row: 3, colSpan: 2, rowSpan: 2 },
14
+ { col: 1, row: 5, colSpan: 3, rowSpan: 2 },
15
+ ],
16
+ };
@@ -0,0 +1,15 @@
1
+ declare const _default: {
2
+ canvas: {
3
+ width: number;
4
+ height: number;
5
+ columns: number;
6
+ rows: number;
7
+ };
8
+ slots: {
9
+ col: number;
10
+ row: number;
11
+ colSpan: number;
12
+ rowSpan: number;
13
+ }[];
14
+ };
15
+ export default _default;
@@ -0,0 +1,13 @@
1
+ export default {
2
+ canvas: {
3
+ width: 2800,
4
+ height: 4200,
5
+ columns: 2,
6
+ rows: 3,
7
+ },
8
+ slots: [
9
+ { col: 1, row: 1, colSpan: 2, rowSpan: 1 },
10
+ { col: 1, row: 2, colSpan: 1, rowSpan: 2 },
11
+ { col: 2, row: 2, colSpan: 1, rowSpan: 2 },
12
+ ],
13
+ };