pulp-image 0.1.7 โ 0.1.8
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/CHANGELOG.md +53 -0
- package/README.md +43 -254
- package/ROADMAP.md +133 -0
- package/bin/pulp.js +1 -1
- package/package.json +11 -3
- package/ui/app.js +41 -9
- package/ui/index.html +19 -14
- package/ui/styles.css +4 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to Pulp Image will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/), and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## [Unreleased]
|
|
10
|
+
|
|
11
|
+
See [Roadmap](ROADMAP.md) for upcoming features (v0.2.0: UI Redesign, Rotate, Flip, Grayscale, Auto-Orient).
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## [0.1.8] - 2026-01-13
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
- Streamlined README with quick links and features grid
|
|
19
|
+
- Added public roadmap and changelog
|
|
20
|
+
- Updated project slogan
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## [0.1.7] - 2026-01-12
|
|
25
|
+
|
|
26
|
+
### Added
|
|
27
|
+
- Auto suffix option to add dimensions to filenames
|
|
28
|
+
- Custom suffix support for output filenames
|
|
29
|
+
- Rename patterns with tokens {name}, {ext}, {index} (UI only)
|
|
30
|
+
|
|
31
|
+
### Fixed
|
|
32
|
+
- Minor bug fixes and improvements
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## [0.1.0] - Initial Release
|
|
37
|
+
|
|
38
|
+
### Added
|
|
39
|
+
- **CLI Tool**: Full command-line interface for image processing
|
|
40
|
+
- **Browser UI**: Launch with `pulp ui`, works offline, no uploads
|
|
41
|
+
- **Format Conversion**: PNG, JPG, WebP, AVIF, GIF, TIFF
|
|
42
|
+
- **Resize**: By width, height, or exact dimensions
|
|
43
|
+
- **Quality Control**: Compression quality 1-100
|
|
44
|
+
- **Lossless Mode**: For WebP and AVIF
|
|
45
|
+
- **Transparency Handling**: Flatten with custom background color
|
|
46
|
+
- **Batch Processing**: Process entire folders
|
|
47
|
+
- **Custom Output Directory**: Save files anywhere
|
|
48
|
+
- **Overwrite Protection**: Skip or overwrite existing files
|
|
49
|
+
- **Delete Originals**: Remove source files after processing (CLI only)
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
*For upcoming features, see the [Roadmap](ROADMAP.md).*
|
package/README.md
CHANGED
|
@@ -1,303 +1,92 @@
|
|
|
1
1
|
# pulp-image
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Full-featured image processing CLI with a browser UI. 100% local.
|
|
4
4
|
|
|
5
5
|

|
|
6
6
|

|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
- ๐ผ๏ธ **Resize images** with aspect ratio preservation
|
|
11
|
-
- ๐ **Convert formats** (PNG, JPG, WebP, AVIF)
|
|
12
|
-
- ๐ฆ **Batch process** entire directories
|
|
13
|
-
- ๐ก๏ธ **Safety-first** defaults (no overwrites, no accidental deletions)
|
|
14
|
-
- ๐ **Detailed statistics** and summary reports
|
|
15
|
-
- ๐จ **Transparency handling** with customizable backgrounds
|
|
16
|
-
- โก **Optimization** with quality and lossless options
|
|
17
|
-
|
|
18
|
-
## Installation
|
|
8
|
+
**[Website](https://pulp.run)** ยท **[CLI Docs](https://pulp.run/cli.html)** ยท **[UI Docs](https://pulp.run/ui.html)** ยท **[Roadmap](ROADMAP.md)** ยท **[Changelog](CHANGELOG.md)**
|
|
19
9
|
|
|
20
|
-
|
|
10
|
+
---
|
|
21
11
|
|
|
22
|
-
|
|
23
|
-
npm install -g pulp-image
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
This is a global CLI. Installing with `-g` makes the `pulp` command available system-wide.
|
|
27
|
-
|
|
28
|
-
### Requirements
|
|
29
|
-
|
|
30
|
-
- Node.js >= 18.0.0
|
|
31
|
-
- npm (comes with Node.js)
|
|
32
|
-
|
|
33
|
-
## Quick Start
|
|
12
|
+
## Features
|
|
34
13
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
14
|
+
| | | |
|
|
15
|
+
|:--|:--|:--|
|
|
16
|
+
| ๐ผ๏ธ **Resize** | ๐ **Convert Formats** | ๐ฆ **Batch Process** |
|
|
17
|
+
| ๐จ **Transparency** | โก **Quality Control** | ๐ก๏ธ **Safety-First** |
|
|
18
|
+
| ๐ **Browser UI** | ๐ **Custom Output** | ๐ท๏ธ **Auto Naming** |
|
|
38
19
|
|
|
39
|
-
|
|
40
|
-
pulp image.png --format webp
|
|
20
|
+
---
|
|
41
21
|
|
|
42
|
-
|
|
43
|
-
pulp ./images --format webp --out ./output
|
|
44
|
-
```
|
|
22
|
+
## Installation
|
|
45
23
|
|
|
46
|
-
|
|
24
|
+
### CLI (npm)
|
|
47
25
|
|
|
48
26
|
```bash
|
|
49
|
-
|
|
27
|
+
npm install -g pulp-image
|
|
50
28
|
```
|
|
51
29
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
- `[input]` - Input file or directory (required)
|
|
55
|
-
|
|
56
|
-
### Common Options
|
|
57
|
-
|
|
58
|
-
#### Resize
|
|
59
|
-
- `-w, --width <number>` - Output width in pixels (preserves aspect ratio if height not specified)
|
|
60
|
-
- `-h, --height <number>` - Output height in pixels (preserves aspect ratio if width not specified)
|
|
61
|
-
|
|
62
|
-
#### Format
|
|
63
|
-
- `-f, --format <format>` - Output format: `png`, `jpg`, `webp`, or `avif`
|
|
64
|
-
|
|
65
|
-
#### Output
|
|
66
|
-
- `-o, --out <dir>` - Output directory (default: `./pulp-image-results`)
|
|
67
|
-
- **Why use --out?** This keeps your original files safe and organizes processed images in a dedicated folder. The output directory is created automatically if it doesn't exist.
|
|
30
|
+
Requires Node.js >= 18.0.0
|
|
68
31
|
|
|
69
|
-
|
|
70
|
-
- `--quality <number>` - Quality for lossy formats (1-100). Defaults: JPG=80, WebP=80, AVIF=50
|
|
71
|
-
- `--lossless` - Use lossless compression where supported (PNG, WebP, AVIF)
|
|
32
|
+
### Portable UI (No Install)
|
|
72
33
|
|
|
73
|
-
|
|
74
|
-
- **PNG**: Always lossless (no quality setting available)
|
|
75
|
-
- **JPG**: Always lossy, default quality 80 (does not support lossless)
|
|
76
|
-
- **WebP**: Lossy by default (quality 80), can use `--lossless` for lossless compression
|
|
77
|
-
- **AVIF**: Lossy by default (quality 50), can use `--lossless` for lossless compression
|
|
34
|
+
Download the portable UI for your platform. No Node.js or npm required:
|
|
78
35
|
|
|
79
|
-
**
|
|
36
|
+
**[Download Latest Release](https://github.com/rebelliongeeks/pulp-image/releases/latest)**
|
|
80
37
|
|
|
81
|
-
|
|
82
|
-
- `--background <color>` - Background color for flattening transparency (hex format, default: `#ffffff`)
|
|
83
|
-
- `--alpha-mode <mode>` - Alpha handling: `flatten` (default) or `error`
|
|
38
|
+
---
|
|
84
39
|
|
|
85
|
-
|
|
86
|
-
- `--overwrite` - Overwrite existing output files (default: skip existing files)
|
|
87
|
-
- `--delete-original` - Delete original files after successful processing (only if paths differ)
|
|
88
|
-
|
|
89
|
-
#### Other
|
|
90
|
-
- `-v, --verbose` - Show detailed per-file processing information
|
|
91
|
-
- `--help` - Display help information
|
|
92
|
-
- `--version` - Show version number
|
|
93
|
-
|
|
94
|
-
## Examples
|
|
95
|
-
|
|
96
|
-
### Resize Images
|
|
40
|
+
## Quick Start
|
|
97
41
|
|
|
98
42
|
```bash
|
|
99
|
-
# Resize
|
|
43
|
+
# Resize an image
|
|
100
44
|
pulp image.png --width 800
|
|
101
45
|
|
|
102
|
-
#
|
|
103
|
-
pulp image.png --height 600
|
|
104
|
-
|
|
105
|
-
# Resize to exact dimensions
|
|
106
|
-
pulp image.png --width 800 --height 600
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
### Format Conversion
|
|
110
|
-
|
|
111
|
-
```bash
|
|
112
|
-
# Convert PNG to WebP (preserves transparency)
|
|
46
|
+
# Convert to WebP
|
|
113
47
|
pulp image.png --format webp
|
|
114
48
|
|
|
115
|
-
#
|
|
116
|
-
pulp image.png --format jpg
|
|
117
|
-
|
|
118
|
-
# Convert with custom background color
|
|
119
|
-
pulp image.png --format jpg --background "#ff0000"
|
|
120
|
-
|
|
121
|
-
# Convert to lossless WebP
|
|
122
|
-
pulp image.png --format webp --lossless
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
### Suffix Options
|
|
126
|
-
|
|
127
|
-
```bash
|
|
128
|
-
# Auto suffix (adds size to filename)
|
|
129
|
-
pulp image.png --width 800 --auto-suffix
|
|
130
|
-
# Output: image-800w.png
|
|
131
|
-
|
|
132
|
-
# Custom suffix
|
|
133
|
-
pulp image.png --suffix "optimized"
|
|
134
|
-
# Output: image-optimized.png
|
|
135
|
-
|
|
136
|
-
# Combined suffixes (auto first, custom second)
|
|
137
|
-
pulp image.png --width 800 --auto-suffix --suffix "thumb"
|
|
138
|
-
# Output: image-800w-thumb.png
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
### Batch Processing
|
|
142
|
-
|
|
143
|
-
```bash
|
|
144
|
-
# Process all images in a directory
|
|
145
|
-
pulp ./images --format webp --out ./output
|
|
146
|
-
|
|
147
|
-
# Resize all images with auto-suffix
|
|
148
|
-
pulp ./images --width 800 --auto-suffix --out ./output
|
|
149
|
-
|
|
150
|
-
# Verbose mode (shows per-file details)
|
|
151
|
-
pulp ./images --format webp --out ./output --verbose
|
|
152
|
-
|
|
153
|
-
# Overwrite existing files
|
|
154
|
-
pulp ./images --format webp --out ./output --overwrite
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
### Safety Features
|
|
158
|
-
|
|
159
|
-
```bash
|
|
160
|
-
# Safe processing (output to separate directory)
|
|
161
|
-
pulp image.png --format webp --out ./pulp-image-results
|
|
162
|
-
|
|
163
|
-
# Overwrite existing output files
|
|
164
|
-
pulp image.png --format webp --out ./pulp-image-results --overwrite
|
|
165
|
-
|
|
166
|
-
# Delete original after successful processing
|
|
167
|
-
pulp image.png --format webp --out ./pulp-image-results --delete-original
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
## Safety Features
|
|
171
|
-
|
|
172
|
-
pulp-image is designed with safety in mind:
|
|
173
|
-
|
|
174
|
-
- **No overwrites by default** - Existing output files are skipped unless `--overwrite` is used
|
|
175
|
-
- **Delete original safety** - Only deletes after successful processing and only if input/output paths differ
|
|
176
|
-
- **Same path protection** - Prevents accidental in-place overwrites
|
|
177
|
-
- **Batch resilience** - Continues processing even if individual files fail
|
|
178
|
-
- **Clear error messages** - Helpful guidance when something goes wrong
|
|
179
|
-
|
|
180
|
-
## Output Directory (--out)
|
|
181
|
-
|
|
182
|
-
The `--out` option specifies where processed images are saved. Here's why it's useful:
|
|
183
|
-
|
|
184
|
-
- **Keeps originals safe** - Your source files remain untouched
|
|
185
|
-
- **Organizes outputs** - All processed images in one place
|
|
186
|
-
- **Prevents accidents** - No risk of overwriting originals
|
|
187
|
-
- **Default location** - Uses `./pulp-image-results` if not specified
|
|
188
|
-
- **Auto-creation** - Creates the directory if it doesn't exist
|
|
189
|
-
|
|
190
|
-
Example:
|
|
191
|
-
```bash
|
|
192
|
-
# Process images and save to ./output directory
|
|
49
|
+
# Batch process a folder
|
|
193
50
|
pulp ./images --format webp --out ./output
|
|
194
51
|
|
|
195
|
-
#
|
|
196
|
-
|
|
197
|
-
```
|
|
198
|
-
|
|
199
|
-
## Supported Formats
|
|
200
|
-
|
|
201
|
-
### Input Formats
|
|
202
|
-
- PNG
|
|
203
|
-
- JPG/JPEG
|
|
204
|
-
- WebP
|
|
205
|
-
- AVIF
|
|
206
|
-
|
|
207
|
-
### Output Formats
|
|
208
|
-
- PNG
|
|
209
|
-
- JPG
|
|
210
|
-
- WebP
|
|
211
|
-
- AVIF
|
|
212
|
-
|
|
213
|
-
## Compression & Quality
|
|
214
|
-
|
|
215
|
-
### Default Compression Behavior
|
|
216
|
-
|
|
217
|
-
Each format has different default compression behavior:
|
|
218
|
-
|
|
219
|
-
- **PNG**: Always lossless (no quality setting available)
|
|
220
|
-
- **JPG**: Always lossy, default quality 80 (does not support lossless)
|
|
221
|
-
- **WebP**: Lossy by default (quality 80), supports lossless with `--lossless`
|
|
222
|
-
- **AVIF**: Lossy by default (quality 50), supports lossless with `--lossless`
|
|
223
|
-
|
|
224
|
-
**Important:** Resize operations do NOT affect compression. Resizing only changes image dimensions. Compression/quality is determined by the format and quality settings.
|
|
225
|
-
|
|
226
|
-
### Using Lossless Compression
|
|
52
|
+
# High quality JPG
|
|
53
|
+
pulp image.png --format jpg --quality 95
|
|
227
54
|
|
|
228
|
-
```bash
|
|
229
55
|
# Lossless WebP
|
|
230
56
|
pulp image.png --format webp --lossless
|
|
231
|
-
|
|
232
|
-
# Lossless AVIF
|
|
233
|
-
pulp image.png --format avif --lossless
|
|
234
|
-
|
|
235
|
-
# PNG is already lossless (no flag needed)
|
|
236
|
-
pulp image.jpg --format png
|
|
237
57
|
```
|
|
238
58
|
|
|
239
|
-
|
|
59
|
+
For all options, run `pulp --help` or see the [CLI documentation](https://pulp.run/cli.html).
|
|
240
60
|
|
|
241
|
-
|
|
242
|
-
# High quality JPG
|
|
243
|
-
pulp image.png --format jpg --quality 95
|
|
244
|
-
|
|
245
|
-
# Lower quality WebP (smaller file)
|
|
246
|
-
pulp image.png --format webp --quality 60
|
|
247
|
-
|
|
248
|
-
# Custom AVIF quality
|
|
249
|
-
pulp image.png --format avif --quality 70
|
|
250
|
-
```
|
|
251
|
-
|
|
252
|
-
## Transparency Handling
|
|
61
|
+
---
|
|
253
62
|
|
|
254
|
-
|
|
63
|
+
## Browser UI
|
|
255
64
|
|
|
256
|
-
|
|
257
|
-
- **Custom background**: Use `--background "#color"` to specify a color
|
|
258
|
-
- **Error mode**: Use `--alpha-mode error` to fail instead of flattening
|
|
65
|
+
Launch the browser-based interface:
|
|
259
66
|
|
|
260
|
-
Example:
|
|
261
67
|
```bash
|
|
262
|
-
|
|
263
|
-
pulp image.png --format jpg --background "#ff0000"
|
|
264
|
-
|
|
265
|
-
# Fail if transparency exists
|
|
266
|
-
pulp image.png --format jpg --alpha-mode error
|
|
68
|
+
pulp ui
|
|
267
69
|
```
|
|
268
70
|
|
|
269
|
-
|
|
71
|
+
Opens at `http://localhost:3000`. All processing happens locally, no uploads.
|
|
270
72
|
|
|
271
|
-
pulp
|
|
73
|
+
See the [UI documentation](https://pulp.run/ui.html) for details.
|
|
272
74
|
|
|
273
|
-
|
|
274
|
-
- **Batch summary**: Total files processed, total sizes, overall savings
|
|
275
|
-
- **Skipped files**: Count and reasons (in verbose mode)
|
|
276
|
-
- **Failed files**: Count and errors (in verbose mode)
|
|
75
|
+
---
|
|
277
76
|
|
|
278
|
-
|
|
279
|
-
```
|
|
280
|
-
โ Processed: 7 file(s)
|
|
281
|
-
Total original size: 10.07 MB
|
|
282
|
-
Total final size: 821.78 KB
|
|
283
|
-
Total saved: 9.26 MB (92.03%)
|
|
284
|
-
```
|
|
77
|
+
## Roadmap
|
|
285
78
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
pulp-image includes a web-based interface for easy image processing:
|
|
79
|
+
See the full [Roadmap](ROADMAP.md) for upcoming features.
|
|
289
80
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
http://localhost:3000
|
|
298
|
-
```
|
|
81
|
+
**Coming soon:**
|
|
82
|
+
- UI Redesign with dark mode
|
|
83
|
+
- Rotate, Flip, Grayscale
|
|
84
|
+
- Blur, Sharpen, Normalize
|
|
85
|
+
- Cropping & Visual Crop Tool
|
|
86
|
+
- Watermarks
|
|
87
|
+
- User Presets
|
|
299
88
|
|
|
300
|
-
|
|
89
|
+
---
|
|
301
90
|
|
|
302
91
|
## License
|
|
303
92
|
|
|
@@ -305,4 +94,4 @@ MIT
|
|
|
305
94
|
|
|
306
95
|
## Author
|
|
307
96
|
|
|
308
|
-
Rebellion Geeks
|
|
97
|
+
[Rebellion Geeks](https://github.com/rebelliongeeks)
|
package/ROADMAP.md
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# Roadmap
|
|
2
|
+
|
|
3
|
+
> Full-featured image processing CLI with a browser UI. 100% local.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## โ
v0.1.x (Current)
|
|
8
|
+
|
|
9
|
+
| Feature | Description |
|
|
10
|
+
|---------|-------------|
|
|
11
|
+
| ~~**Format Conversion**~~ | ~~Convert between PNG, JPG, WebP, AVIF, GIF, TIFF~~ |
|
|
12
|
+
| ~~**Resize**~~ | ~~Resize by width, height, or both with auto aspect ratio~~ |
|
|
13
|
+
| ~~**Quality Control**~~ | ~~Adjust compression quality (1-100)~~ |
|
|
14
|
+
| ~~**Lossless Mode**~~ | ~~Preserve full quality for WebP and AVIF~~ |
|
|
15
|
+
| ~~**Transparency Handling**~~ | ~~Flatten transparent areas with custom background color~~ |
|
|
16
|
+
| ~~**Custom Output Directory**~~ | ~~Save processed files to any folder~~ |
|
|
17
|
+
| ~~**Auto Suffix**~~ | ~~Add dimensions to filename automatically~~ |
|
|
18
|
+
| ~~**Rename Patterns**~~ | ~~Use tokens like {name}, {ext}, {index} for output names (UI)~~ |
|
|
19
|
+
| ~~**Batch Processing**~~ | ~~Process entire folders at once~~ |
|
|
20
|
+
| ~~**Delete Originals**~~ | ~~Remove source files after processing (CLI only)~~ |
|
|
21
|
+
| ~~**Browser-Based UI**~~ | ~~Full-featured interface, works offline, no uploads~~ |
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## ๐ง v0.2.0
|
|
26
|
+
|
|
27
|
+
| Feature | Description |
|
|
28
|
+
|---------|-------------|
|
|
29
|
+
| **UI Redesign** | Modern tabbed interface with dark mode |
|
|
30
|
+
| **Rotate** | Rotate images by 90ยฐ, 180ยฐ, 270ยฐ, or custom angle |
|
|
31
|
+
| **Flip / Mirror** | Flip vertically or horizontally |
|
|
32
|
+
| **Grayscale** | Convert images to black and white |
|
|
33
|
+
| **Auto-Orient** | Fix photos that appear sideways or upside down |
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## ๐ v0.3.0
|
|
38
|
+
|
|
39
|
+
| Feature | Description |
|
|
40
|
+
|---------|-------------|
|
|
41
|
+
| **Blur** | Soften images with adjustable intensity |
|
|
42
|
+
| **Sharpen** | Enhance detail and clarity |
|
|
43
|
+
| **Normalize** | Auto-adjust contrast for better exposure |
|
|
44
|
+
| **Brightness** | Adjust overall brightness |
|
|
45
|
+
| **Saturation** | Adjust color intensity |
|
|
46
|
+
| **Gamma Correction** | Adjust brightness curve |
|
|
47
|
+
| **Hue Shift** | Rotate colors on the color wheel |
|
|
48
|
+
| **Negate / Invert** | Invert all colors (negative effect) |
|
|
49
|
+
| **Tint** | Apply color overlay |
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## ๐ v0.4.0
|
|
54
|
+
|
|
55
|
+
| Feature | Description |
|
|
56
|
+
|---------|-------------|
|
|
57
|
+
| **Trim Whitespace** | Auto-remove uniform borders from images |
|
|
58
|
+
| **Crop by Coordinates** | Crop to specific pixel coordinates |
|
|
59
|
+
| **Visual Crop Tool** | Drag-and-drop crop selection (UI) |
|
|
60
|
+
| **Aspect Ratio Crop** | Crop to common ratios (16:9, 4:3, 1:1) |
|
|
61
|
+
| **Blur Region** | Blur faces or sensitive areas for privacy |
|
|
62
|
+
| **Pixelate Region** | Pixelate specific areas for censoring |
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## ๐ v0.5.0
|
|
67
|
+
|
|
68
|
+
| Feature | Description |
|
|
69
|
+
|---------|-------------|
|
|
70
|
+
| **Add Padding** | Add space around image with custom color |
|
|
71
|
+
| **Add Border** | Add visible frame around image |
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## ๐ v0.6.0
|
|
76
|
+
|
|
77
|
+
| Feature | Description |
|
|
78
|
+
|---------|-------------|
|
|
79
|
+
| **Image Watermark** | Add logo or image overlay |
|
|
80
|
+
| **Watermark Position** | Place in corners, center, or custom coordinates |
|
|
81
|
+
| **Watermark Opacity** | Adjust transparency (0-100%) |
|
|
82
|
+
| **Watermark Scale** | Size relative to image or absolute pixels |
|
|
83
|
+
| **Watermark Tile** | Repeat watermark across entire image |
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## ๐ v0.7.0
|
|
88
|
+
|
|
89
|
+
| Feature | Description |
|
|
90
|
+
|---------|-------------|
|
|
91
|
+
| **Save Preset** | Save current settings as named preset |
|
|
92
|
+
| **Load Preset** | Apply saved presets |
|
|
93
|
+
| **Built-in Presets** | Ready-to-use presets (web, thumbnail, social media) |
|
|
94
|
+
| **Export/Import Presets** | Share presets between devices or users |
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## ๐ v0.8.0
|
|
99
|
+
|
|
100
|
+
| Feature | Description |
|
|
101
|
+
|---------|-------------|
|
|
102
|
+
| **Multi-Format Export** | Export same image to multiple formats at once |
|
|
103
|
+
| **Multi-Size Export** | Export same image at multiple sizes at once |
|
|
104
|
+
| **Progressive JPEG** | Enable progressive loading (blurry to sharp) |
|
|
105
|
+
| **PNG Compression** | Fine-tune PNG compression level |
|
|
106
|
+
| **WebP/AVIF Effort** | Control encoding effort for smaller files |
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## ๐ฏ v1.0.0 (Stable Release)
|
|
111
|
+
|
|
112
|
+
- All features from v0.2.0 through v0.8.0 complete
|
|
113
|
+
- Comprehensive documentation
|
|
114
|
+
- Stable CLI (no breaking changes)
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## ๐ฎ Future (v1.1.0+)
|
|
119
|
+
|
|
120
|
+
These features may be added after the stable release:
|
|
121
|
+
|
|
122
|
+
| Feature | Description |
|
|
123
|
+
|---------|-------------|
|
|
124
|
+
| **Preserve Metadata** | Keep original EXIF data instead of stripping |
|
|
125
|
+
| **Custom ICC Profile** | Embed specific color profiles |
|
|
126
|
+
| **Median Filter** | Reduce noise while preserving edges |
|
|
127
|
+
| **Pure Black & White** | Convert to only black and white pixels (stencil effect) |
|
|
128
|
+
| **Animated GIF/WebP** | Process animated images |
|
|
129
|
+
| **Extract Frame** | Get single frame from animation |
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
*No fixed release dates. Features ship when ready.*
|
package/bin/pulp.js
CHANGED
|
@@ -26,7 +26,7 @@ const banner = getBanner(pkg.version);
|
|
|
26
26
|
|
|
27
27
|
program
|
|
28
28
|
.name('pulp')
|
|
29
|
-
.description('
|
|
29
|
+
.description('Full-featured image processing CLI with a browser UI. 100% local.')
|
|
30
30
|
.version(pkg.version)
|
|
31
31
|
.addHelpText('before', chalk.cyan(banner))
|
|
32
32
|
.argument('[input]', 'Input file or directory')
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pulp-image",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.1.8",
|
|
4
|
+
"description": "Full-featured image processing CLI with a browser UI. 100% local.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "bin/pulp.js",
|
|
7
7
|
"bin": {
|
|
@@ -15,7 +15,15 @@
|
|
|
15
15
|
"resize",
|
|
16
16
|
"convert",
|
|
17
17
|
"optimize",
|
|
18
|
-
"cli"
|
|
18
|
+
"cli",
|
|
19
|
+
"ui",
|
|
20
|
+
"browser",
|
|
21
|
+
"local",
|
|
22
|
+
"batch",
|
|
23
|
+
"webp",
|
|
24
|
+
"avif",
|
|
25
|
+
"png",
|
|
26
|
+
"jpg"
|
|
19
27
|
],
|
|
20
28
|
"author": "Rebellion Geeks",
|
|
21
29
|
"license": "MIT",
|
package/ui/app.js
CHANGED
|
@@ -1222,28 +1222,49 @@ function setupHelpSubnav() {
|
|
|
1222
1222
|
|
|
1223
1223
|
// Flag to temporarily disable scroll-based updates after click
|
|
1224
1224
|
let isClickScrolling = false;
|
|
1225
|
+
let clickedSectionId = null;
|
|
1225
1226
|
|
|
1226
1227
|
// Navigation links - smooth scroll
|
|
1227
1228
|
links.forEach(link => {
|
|
1228
1229
|
link.addEventListener('click', (e) => {
|
|
1229
1230
|
e.preventDefault();
|
|
1231
|
+
|
|
1232
|
+
// IMMEDIATELY block scroll detection before anything else
|
|
1233
|
+
isClickScrolling = true;
|
|
1234
|
+
|
|
1230
1235
|
const targetId = link.getAttribute('href').slice(1);
|
|
1231
1236
|
const target = document.getElementById(targetId);
|
|
1232
1237
|
|
|
1233
1238
|
if (target) {
|
|
1239
|
+
clickedSectionId = targetId;
|
|
1240
|
+
|
|
1234
1241
|
// Set active immediately on click
|
|
1235
1242
|
links.forEach(l => l.classList.remove('active'));
|
|
1236
1243
|
link.classList.add('active');
|
|
1237
1244
|
|
|
1238
|
-
//
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1245
|
+
// Use requestAnimationFrame to ensure DOM update before scroll
|
|
1246
|
+
requestAnimationFrame(() => {
|
|
1247
|
+
target.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
|
1248
|
+
});
|
|
1242
1249
|
|
|
1243
1250
|
// Re-enable scroll updates after animation completes
|
|
1244
1251
|
setTimeout(() => {
|
|
1245
|
-
|
|
1246
|
-
|
|
1252
|
+
// Force the clicked section to stay active after scroll settles
|
|
1253
|
+
if (clickedSectionId) {
|
|
1254
|
+
links.forEach(l => {
|
|
1255
|
+
const id = l.getAttribute('href').slice(1);
|
|
1256
|
+
l.classList.toggle('active', id === clickedSectionId);
|
|
1257
|
+
});
|
|
1258
|
+
}
|
|
1259
|
+
// Small additional delay before allowing scroll detection again
|
|
1260
|
+
setTimeout(() => {
|
|
1261
|
+
isClickScrolling = false;
|
|
1262
|
+
clickedSectionId = null;
|
|
1263
|
+
}, 150);
|
|
1264
|
+
}, 900);
|
|
1265
|
+
} else {
|
|
1266
|
+
// Reset if target not found
|
|
1267
|
+
isClickScrolling = false;
|
|
1247
1268
|
}
|
|
1248
1269
|
});
|
|
1249
1270
|
});
|
|
@@ -1256,21 +1277,32 @@ function setupHelpSubnav() {
|
|
|
1256
1277
|
// Only track when help tab is visible
|
|
1257
1278
|
if (!helpTab || !helpTab.classList.contains('active')) return;
|
|
1258
1279
|
|
|
1259
|
-
//
|
|
1280
|
+
// Find the section whose top is closest to (but not below) the viewport top
|
|
1281
|
+
// This handles cases where sections can't scroll all the way to the top
|
|
1260
1282
|
let currentSection = '';
|
|
1261
|
-
|
|
1283
|
+
let bestTop = -Infinity;
|
|
1284
|
+
const threshold = 150; // How far below viewport top a section can be and still be "current"
|
|
1262
1285
|
|
|
1263
1286
|
links.forEach(link => {
|
|
1264
1287
|
const targetId = link.getAttribute('href').slice(1);
|
|
1265
1288
|
const section = document.getElementById(targetId);
|
|
1266
1289
|
if (section) {
|
|
1267
1290
|
const rect = section.getBoundingClientRect();
|
|
1268
|
-
if
|
|
1291
|
+
// Section is "in view" if its top is above the threshold
|
|
1292
|
+
// Pick the one with the largest top value that's still <= threshold
|
|
1293
|
+
// (i.e., the one closest to the top but still visible)
|
|
1294
|
+
if (rect.top <= threshold && rect.top > bestTop) {
|
|
1295
|
+
bestTop = rect.top;
|
|
1269
1296
|
currentSection = targetId;
|
|
1270
1297
|
}
|
|
1271
1298
|
}
|
|
1272
1299
|
});
|
|
1273
1300
|
|
|
1301
|
+
// Fallback: if no section found, use first one
|
|
1302
|
+
if (!currentSection && links.length > 0) {
|
|
1303
|
+
currentSection = links[0].getAttribute('href').slice(1);
|
|
1304
|
+
}
|
|
1305
|
+
|
|
1274
1306
|
// Update active class
|
|
1275
1307
|
if (currentSection) {
|
|
1276
1308
|
links.forEach(link => {
|
package/ui/index.html
CHANGED
|
@@ -235,7 +235,8 @@
|
|
|
235
235
|
<span class="toggle-text">Auto Suffix</span>
|
|
236
236
|
</label>
|
|
237
237
|
<div class="input-helper">
|
|
238
|
-
Automatically add size-based suffix: -800w (width), -600h (height), -800x600 (both)
|
|
238
|
+
Automatically add size-based suffix: -800w (width), -600h (height), -800x600 (both).<br>
|
|
239
|
+
<strong>Note:</strong> If using a rename pattern above, add dimensions directly there instead, this option won't apply.
|
|
239
240
|
</div>
|
|
240
241
|
<div id="auto-suffix-preview" class="preview-text"></div>
|
|
241
242
|
</div>
|
|
@@ -294,11 +295,15 @@
|
|
|
294
295
|
</nav>
|
|
295
296
|
|
|
296
297
|
<!-- Welcome -->
|
|
297
|
-
<
|
|
298
|
-
<
|
|
299
|
-
<p
|
|
300
|
-
|
|
301
|
-
|
|
298
|
+
<section id="help-welcome">
|
|
299
|
+
<h2>Welcome to Pulp Image UI</h2>
|
|
300
|
+
<p style="margin-bottom: 0.75rem; color: var(--text-secondary);">This browser-based UI includes all features of the CLI, except automatic deletion of original files, as browser security prevents file deletion. The CLI is optional and only needed for automation, advanced workflows, or if you prefer working in the terminal.</p>
|
|
301
|
+
|
|
302
|
+
<p style="margin-bottom: 0.25rem;"><strong>Everything Happens Locally</strong></p>
|
|
303
|
+
<p style="margin-bottom: 0.75rem; color: var(--text-secondary);">All image processing runs directly on your computer. No files are uploaded to the internet. Your images stay private and processing remains fast. Pulp Image UI works fully offline, even if your browser shows upload notifications.</p>
|
|
304
|
+
|
|
305
|
+
<p style="color: var(--text-secondary);">If you downloaded this UI as a portable package from the <a target="_blank" href="https://pulp.run">Pulp</a> website, you do not need to install the CLI. If you want to use the CLI separately, see the <a href="#help-install">installation guide</a>.</p>
|
|
306
|
+
</section>
|
|
302
307
|
|
|
303
308
|
<!-- Compression Behavior -->
|
|
304
309
|
|
|
@@ -313,7 +318,7 @@
|
|
|
313
318
|
<tr><td><code>avif</code></td><td>โ Yes</td><td>Lossy or lossless</td><td>50</td></tr>
|
|
314
319
|
</tbody>
|
|
315
320
|
</table>
|
|
316
|
-
<p style="margin-top: 1rem; color: var(--text-secondary); font-size: 0.9rem;"><em>Note: Resize does not affect compression
|
|
321
|
+
<p style="margin-top: 1rem; color: var(--text-secondary); font-size: 0.9rem;"><em>Note: Resize does not affect compression, it only changes dimensions.</em></p>
|
|
317
322
|
</section>
|
|
318
323
|
|
|
319
324
|
<!-- UI Options Guide -->
|
|
@@ -361,8 +366,8 @@
|
|
|
361
366
|
<h3 class="help-subsection-title">Alpha (Transparency)</h3>
|
|
362
367
|
<p style="margin-bottom: 0.5rem;">When converting to JPG (no transparency):</p>
|
|
363
368
|
<ul style="margin: 0 0 0 1.25rem; color: var(--text-secondary);">
|
|
364
|
-
<li><strong>Flatten</strong>
|
|
365
|
-
<li><strong>Error</strong>
|
|
369
|
+
<li><strong>Flatten</strong> = Fill transparent areas with background color</li>
|
|
370
|
+
<li><strong>Error</strong> = Fail if image has transparency</li>
|
|
366
371
|
</ul>
|
|
367
372
|
</div>
|
|
368
373
|
|
|
@@ -374,6 +379,7 @@
|
|
|
374
379
|
<li>Height 600 โ <code>photo-600h.webp</code></li>
|
|
375
380
|
<li>Both โ <code>photo-800x600.webp</code></li>
|
|
376
381
|
</ul>
|
|
382
|
+
<p style="margin-top: 0.5rem; font-size: 0.85rem; color: var(--text-muted);"><em><strong>Note:</strong> If using a rename pattern, add dimensions directly in the pattern(auto suffix won't apply).</em></p>
|
|
377
383
|
</div>
|
|
378
384
|
|
|
379
385
|
<div class="help-subsection">
|
|
@@ -381,9 +387,9 @@
|
|
|
381
387
|
<p style="margin-bottom: 0.5rem;">Flexible output filename generation. <em>CLI users already have shell tools for renaming that can be piped with Pulp.</em></p>
|
|
382
388
|
<p style="margin-bottom: 0.5rem;"><strong>Supported Tokens:</strong></p>
|
|
383
389
|
<ul style="margin: 0 0 1rem 1.25rem; color: var(--text-secondary);">
|
|
384
|
-
<li><code>{name}</code>
|
|
385
|
-
<li><code>{ext}</code>
|
|
386
|
-
<li><code>{index}</code>
|
|
390
|
+
<li><code>{name}</code> = Original basename (without extension)</li>
|
|
391
|
+
<li><code>{ext}</code> = Output extension (without leading dot)</li>
|
|
392
|
+
<li><code>{index}</code> = 1-based index in batch</li>
|
|
387
393
|
</ul>
|
|
388
394
|
<table class="help-table">
|
|
389
395
|
<thead><tr><th>Pattern</th><th>Result</th></tr></thead>
|
|
@@ -424,7 +430,7 @@
|
|
|
424
430
|
|
|
425
431
|
<section id="help-install">
|
|
426
432
|
<h2>Installing the CLI (Optional)</h2>
|
|
427
|
-
<p>The CLI is optional.
|
|
433
|
+
<p>The CLI is optional. Install it if you prefer working in the terminal, need automation or scripting, or want access to CLI-only features such as <code>--delete-original</code>.</p>
|
|
428
434
|
|
|
429
435
|
<div class="terminal-example">
|
|
430
436
|
<div class="terminal-example-header">
|
|
@@ -843,7 +849,6 @@
|
|
|
843
849
|
<li>You're new to the tool</li>
|
|
844
850
|
<li>You want visual feedback and guidance</li>
|
|
845
851
|
<li>You need to understand option combinations</li>
|
|
846
|
-
<li>You want to keep originals safe (UI processes copies)</li>
|
|
847
852
|
<li>You prefer point-and-click interfaces</li>
|
|
848
853
|
</ul>
|
|
849
854
|
</div>
|