wasm-image-processor 0.5.0 → 0.6.0
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/README.md +207 -115
- package/package.json +1 -1
- package/wasm_image_processor.d.ts +121 -34
- package/wasm_image_processor.js +5 -1
- package/wasm_image_processor_bg.js +430 -116
- package/wasm_image_processor_bg.wasm +0 -0
package/README.md
CHANGED
|
@@ -1,175 +1,267 @@
|
|
|
1
1
|
# WASM Image Processor
|
|
2
|
-
> Process images offline in the Browser.
|
|
3
2
|
|
|
4
|
-
|
|
3
|
+
> High-performance client-side image processing powered by Rust and WebAssembly
|
|
5
4
|
|
|
6
|
-
|
|
5
|
+
Process images entirely in the browser with near-native performance. No server uploads, works offline, respects user privacy.
|
|
7
6
|
|
|
8
|
-
|
|
7
|
+
**[Live Demo](https://wasm-ip-demo.vercel.app)** | **[Full Documentation](https://wip-docs.vercel.app)** | **[npm Package](https://www.npmjs.com/package/wasm-image-processor)**
|
|
9
8
|
|
|
10
|
-
|
|
11
|
-
- **High Performance**: Powered by Rust and WebAssembly
|
|
12
|
-
- **No Data Transfer**: Images never leave your device
|
|
13
|
-
- **PWA Icon Generation**: Create complete icon sets for Progressive Web Apps
|
|
14
|
-
- **Multiple Formats**: Support for JPEG, PNG, WebP, and more
|
|
15
|
-
- **Batch Processing**: Generate multiple sizes from a single image
|
|
9
|
+
---
|
|
16
10
|
|
|
17
|
-
##
|
|
11
|
+
## Quick Start
|
|
18
12
|
|
|
19
|
-
|
|
13
|
+
### For JavaScript Users
|
|
20
14
|
|
|
21
|
-
|
|
22
|
-
|
|
15
|
+
```bash
|
|
16
|
+
npm install wasm-image-processor
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
**Vite users:** Install `vite-plugin-wasm` and add it to your config (see [setup guide](https://wip-docs.vercel.app/getting-started.html#vite-configuration))
|
|
23
20
|
|
|
24
|
-
|
|
21
|
+
```javascript
|
|
22
|
+
import { resize_square, blur, grayscale } from "wasm-image-processor";
|
|
25
23
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
- Maintain aspect ratio or force specific dimensions
|
|
29
|
-
- High-quality filtering algorithms
|
|
24
|
+
// Resize an image to 512x512
|
|
25
|
+
const resizedBytes = resize_square(imageUint8Array, 512);
|
|
30
26
|
|
|
27
|
+
// Apply Gaussian blur
|
|
28
|
+
const blurredBytes = blur(imageUint8Array, 5.0);
|
|
31
29
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
npm i wasm-image-processor
|
|
30
|
+
// Convert to grayscale
|
|
31
|
+
const grayBytes = grayscale(imageUint8Array);
|
|
35
32
|
```
|
|
36
33
|
|
|
37
|
-
|
|
34
|
+
**Key features:**
|
|
35
|
+
- Auto-initializes WASM (no manual setup)
|
|
36
|
+
- ~150KB gzipped bundle size
|
|
37
|
+
- TypeScript types included
|
|
38
|
+
- Supports PNG and JPEG formats
|
|
39
|
+
- See [complete documentation](https://wip-docs.vercel.app) for all functions
|
|
38
40
|
|
|
39
|
-
|
|
41
|
+
---
|
|
40
42
|
|
|
41
|
-
|
|
42
|
-
import { resize_square } from "wasm-image-processor";
|
|
43
|
+
### For Rust Contributors
|
|
43
44
|
|
|
44
|
-
|
|
45
|
-
|
|
45
|
+
**Project structure:**
|
|
46
|
+
```
|
|
47
|
+
src/
|
|
48
|
+
lib.rs # WASM bindings & public API
|
|
49
|
+
processing/ # Core image processing logic
|
|
50
|
+
utils/ # Helpers
|
|
51
|
+
Cargo.toml
|
|
52
|
+
```
|
|
46
53
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
54
|
+
**Local development:**
|
|
55
|
+
```bash
|
|
56
|
+
# Build for web
|
|
57
|
+
wasm-pack build --target web --out-dir pkg
|
|
50
58
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
const uint8Array = new Uint8Array(arrayBuffer)
|
|
59
|
+
# Run tests
|
|
60
|
+
cargo test
|
|
61
|
+
wasm-pack test --headless --firefox
|
|
55
62
|
|
|
56
|
-
|
|
57
|
-
|
|
63
|
+
# Test in browser
|
|
64
|
+
cd example && npm install && npm run dev
|
|
65
|
+
```
|
|
58
66
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
67
|
+
**Key dependencies:**
|
|
68
|
+
- `image = "0.24"` for core processing
|
|
69
|
+
- `wasm-bindgen = "0.2"` for JS interop
|
|
70
|
+
- Safe Rust only, panic-safe for WASM context
|
|
63
71
|
|
|
64
|
-
|
|
65
|
-
}
|
|
72
|
+
**Contributing:** Fork the repo, create a feature branch, and open a PR. See [documentation repo](https://github.com/StanleyWorks/wasm-image-processor-docs) for docs contributions.
|
|
66
73
|
|
|
67
|
-
|
|
68
|
-
})
|
|
69
|
-
```
|
|
74
|
+
---
|
|
70
75
|
|
|
71
|
-
|
|
76
|
+
## Available Functions
|
|
72
77
|
|
|
73
|
-
|
|
78
|
+
**Core Operations:**
|
|
79
|
+
- `resize_square(bytes, size)` - Resize to square dimensions
|
|
80
|
+
- `resize(bytes, width, height)` - Resize to custom dimensions
|
|
81
|
+
- `crop(bytes, x, y, width, height)` - Crop to region
|
|
82
|
+
- `thumbnail(bytes, width, height)` - Generate thumbnail
|
|
74
83
|
|
|
75
|
-
|
|
84
|
+
**Filters & Adjustments:**
|
|
85
|
+
- `blur(bytes, sigma)` - Gaussian blur
|
|
86
|
+
- `fast_blur(bytes, sigma)` - Optimized blur
|
|
87
|
+
- `contrast(bytes, value)` - Adjust contrast (-100 to 100)
|
|
88
|
+
- `brighten(bytes, value)` - Adjust brightness (-100 to 100)
|
|
89
|
+
- `grayscale(bytes)` - Convert to grayscale
|
|
90
|
+
- `invert(bytes)` - Invert colors
|
|
91
|
+
- `hue_rotate(bytes, degrees)` - Rotate hue (0-360)
|
|
76
92
|
|
|
77
|
-
**
|
|
78
|
-
- `
|
|
79
|
-
- `side`: Target width/height in pixels (1-5000)
|
|
93
|
+
**Coming Soon:**
|
|
94
|
+
- `rotate(bytes, degrees)` - Rotate image
|
|
80
95
|
|
|
81
|
-
|
|
82
|
-
- PNG-encoded image data as byte array
|
|
96
|
+
See [full API documentation](https://wip-docs.vercel.app/api.html) with live examples for each function.
|
|
83
97
|
|
|
84
|
-
|
|
85
|
-
```javascript
|
|
86
|
-
const resizedBytes = resize_square(imageBytes, 256);
|
|
87
|
-
const blob = new Blob([new Uint8Array(resizedBytes)], { type: 'image/png' });
|
|
88
|
-
```
|
|
98
|
+
---
|
|
89
99
|
|
|
90
|
-
##
|
|
100
|
+
## Why Use This?
|
|
91
101
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
│ ├── index.html # Basic resizer demo
|
|
98
|
-
│ ├── pwa-generator.html # PWA icon generator
|
|
99
|
-
│ ├── pwa_image_generator.js # Generated JS bindings
|
|
100
|
-
│ └── pwa_image_generator_bg.wasm # Generated WASM binary
|
|
101
|
-
├── pkg/ # wasm-pack output
|
|
102
|
-
├── tests/ # Test files
|
|
103
|
-
├── prep-demo.sh # Copy the build to the demo folder
|
|
104
|
-
├── Cargo.toml
|
|
105
|
-
└── README.md
|
|
106
|
-
```
|
|
102
|
+
**For end users:**
|
|
103
|
+
- Privacy: Images never leave your device
|
|
104
|
+
- Speed: Process images in milliseconds
|
|
105
|
+
- Offline: Works without internet connection
|
|
106
|
+
- Universal: Runs in any modern browser
|
|
107
107
|
|
|
108
|
-
|
|
108
|
+
**For developers:**
|
|
109
|
+
- Rust performance in JavaScript
|
|
110
|
+
- Simple, predictable API
|
|
111
|
+
- Tree-shakeable ES modules
|
|
112
|
+
- No server infrastructure needed
|
|
109
113
|
|
|
110
|
-
|
|
114
|
+
---
|
|
111
115
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
+
## Use Cases
|
|
117
|
+
|
|
118
|
+
**Profile picture editors:**
|
|
119
|
+
Generate multiple sizes for avatars without server round-trips. Resize to 32px, 64px, 128px, 256px instantly in the browser.
|
|
120
|
+
|
|
121
|
+
**Photo galleries & portfolios:**
|
|
122
|
+
Create thumbnails client-side before upload. Apply filters for preview without processing server load.
|
|
123
|
+
|
|
124
|
+
**PWA & offline apps:**
|
|
125
|
+
Process images when users have no internet connection. Perfect for field work apps, travel journals, or offline-first tools.
|
|
116
126
|
|
|
117
|
-
|
|
127
|
+
**Privacy-sensitive applications:**
|
|
128
|
+
Medical imaging viewers, legal document processors, or any app where images contain sensitive data that shouldn't touch external servers.
|
|
118
129
|
|
|
119
|
-
|
|
130
|
+
**Image compression tools:**
|
|
131
|
+
Build "TinyPNG alternatives" that run entirely in the browser. Users maintain full control of their files.
|
|
120
132
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
3. Rebuild with `wasm-pack build --target web`
|
|
124
|
-
4. Update the demo pages to use your new function
|
|
133
|
+
**Batch processing utilities:**
|
|
134
|
+
Resize hundreds of product photos, apply watermarks, or normalize images for e-commerce without server costs or upload time.
|
|
125
135
|
|
|
126
|
-
|
|
136
|
+
**Design tools & editors:**
|
|
137
|
+
Add real-time image adjustments (brightness, contrast, blur) to your web app without heavy JavaScript libraries.
|
|
127
138
|
|
|
128
|
-
**
|
|
129
|
-
|
|
130
|
-
- [x] npm package publication
|
|
131
|
-
- [ ] Comprehensive documentation
|
|
132
|
-
- [x] CI/CD pipeline
|
|
139
|
+
**Form enhancements:**
|
|
140
|
+
Automatically resize large images before form submission to reduce upload size and improve UX.
|
|
133
141
|
|
|
134
|
-
|
|
135
|
-
- [ ] Image format conversion (PNG ↔ JPEG ↔ WebP)
|
|
136
|
-
- [ ] Image compression with quality settings
|
|
137
|
-
- [ ] Batch processing for multiple images
|
|
138
|
-
- [ ] Image filters (blur, sharpen, brightness, contrast)
|
|
139
|
-
- [ ] Custom crop functionality
|
|
140
|
-
- [ ] Image rotation and flipping
|
|
141
|
-
- [ ] Metadata preservation and editing
|
|
142
|
-
- [ ] Advanced resizing algorithms
|
|
142
|
+
---
|
|
143
143
|
|
|
144
144
|
## Browser Support
|
|
145
145
|
|
|
146
146
|
- Chrome/Edge 57+
|
|
147
147
|
- Firefox 52+
|
|
148
148
|
- Safari 11+
|
|
149
|
-
- Any browser with WebAssembly support
|
|
149
|
+
- Any browser with [WebAssembly support](https://caniuse.com/wasm)
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## Complete Example
|
|
154
|
+
|
|
155
|
+
```html
|
|
156
|
+
<input type="file" id="fileInput" />
|
|
157
|
+
<button id="downloadBtn" style="display: none;">Download Processed Image</button>
|
|
158
|
+
|
|
159
|
+
<script type="module">
|
|
160
|
+
import { resize_square, blur } from "wasm-image-processor";
|
|
161
|
+
|
|
162
|
+
const input = document.getElementById("fileInput");
|
|
163
|
+
const downloadBtn = document.getElementById("downloadBtn");
|
|
164
|
+
|
|
165
|
+
input.addEventListener("change", async (e) => {
|
|
166
|
+
const file = e.target.files[0];
|
|
167
|
+
if (!file) return;
|
|
168
|
+
|
|
169
|
+
try {
|
|
170
|
+
// Read file
|
|
171
|
+
const arrayBuffer = await file.arrayBuffer();
|
|
172
|
+
const uint8Array = new Uint8Array(arrayBuffer);
|
|
173
|
+
|
|
174
|
+
// Process: resize and blur
|
|
175
|
+
const resized = resize_square(uint8Array, 512);
|
|
176
|
+
const processed = blur(resized, 2.0);
|
|
177
|
+
|
|
178
|
+
// Create downloadable blob
|
|
179
|
+
const blob = new Blob([processed], { type: "image/png" });
|
|
180
|
+
const url = URL.createObjectURL(blob);
|
|
181
|
+
|
|
182
|
+
// Setup download
|
|
183
|
+
downloadBtn.style.display = "block";
|
|
184
|
+
downloadBtn.onclick = () => {
|
|
185
|
+
const a = document.createElement("a");
|
|
186
|
+
a.href = url;
|
|
187
|
+
a.download = "processed-image.png";
|
|
188
|
+
a.click();
|
|
189
|
+
URL.revokeObjectURL(url);
|
|
190
|
+
};
|
|
191
|
+
} catch (error) {
|
|
192
|
+
console.error("Processing failed:", error);
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
</script>
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
See [more examples](https://wip-docs.vercel.app/examples.html) including Vue, Nuxt, and React patterns.
|
|
199
|
+
|
|
200
|
+
---
|
|
150
201
|
|
|
151
202
|
## Performance
|
|
152
203
|
|
|
153
|
-
Processing
|
|
154
|
-
-
|
|
155
|
-
-
|
|
156
|
-
-
|
|
157
|
-
-
|
|
204
|
+
Processing happens entirely client-side using WebAssembly, providing:
|
|
205
|
+
- Fast processing with near-native performance
|
|
206
|
+
- Complete privacy - images never uploaded
|
|
207
|
+
- Offline capability
|
|
208
|
+
- Zero server costs
|
|
209
|
+
|
|
210
|
+
**Typical operations:**
|
|
211
|
+
- Resize 4K image: ~45ms
|
|
212
|
+
- Apply blur filter: ~30ms
|
|
213
|
+
- Grayscale conversion: ~10ms
|
|
214
|
+
|
|
215
|
+
Performance varies by device and image size.
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
## Documentation
|
|
220
|
+
|
|
221
|
+
- [Getting Started Guide](https://wip-docs.vercel.app/getting-started.html)
|
|
222
|
+
- [Complete API Reference](https://wip-docs.vercel.app/api.html)
|
|
223
|
+
- [Live Examples](https://wip-docs.vercel.app/examples.html)
|
|
224
|
+
- [Changelog](https://wip-docs.vercel.app/changelog.html)
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
## Common Issues
|
|
229
|
+
|
|
230
|
+
**Import errors:** Ensure your bundler supports WebAssembly. Vite users need `vite-plugin-wasm` installed and configured.
|
|
231
|
+
|
|
232
|
+
**"Failed to read image":** Only PNG and JPEG formats are currently supported.
|
|
233
|
+
|
|
234
|
+
**Memory issues:** Large images may cause problems on mobile devices. Consider resizing or adding file size limits.
|
|
235
|
+
|
|
236
|
+
See [troubleshooting guide](https://wip-docs.vercel.app/getting-started.html#troubleshooting) for more help.
|
|
237
|
+
|
|
238
|
+
---
|
|
158
239
|
|
|
159
240
|
## Contributing
|
|
160
241
|
|
|
242
|
+
Contributions welcome! To contribute:
|
|
243
|
+
|
|
161
244
|
1. Fork the repository
|
|
162
|
-
2. Create a feature branch
|
|
163
|
-
3. Commit your changes
|
|
164
|
-
4. Push to
|
|
245
|
+
2. Create a feature branch: `git checkout -b feature/amazing-feature`
|
|
246
|
+
3. Commit your changes: `git commit -m 'Add amazing feature'`
|
|
247
|
+
4. Push to branch: `git push origin feature/amazing-feature`
|
|
165
248
|
5. Open a Pull Request
|
|
166
249
|
|
|
250
|
+
For documentation improvements, contribute to the [docs repository](https://github.com/StanleyWorks/wasm-image-processor-docs).
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
167
254
|
## License
|
|
168
255
|
|
|
169
|
-
|
|
256
|
+
MIT License - see [LICENSE](LICENSE) file for details.
|
|
257
|
+
|
|
258
|
+
---
|
|
170
259
|
|
|
171
260
|
## Acknowledgments
|
|
172
261
|
|
|
173
|
-
|
|
174
|
-
-
|
|
175
|
-
-
|
|
262
|
+
Built with:
|
|
263
|
+
- [Rust](https://www.rust-lang.org/) and [wasm-bindgen](https://rustwasm.github.io/wasm-bindgen/)
|
|
264
|
+
- [image-rs](https://github.com/image-rs/image) crate for image processing
|
|
265
|
+
- Inspired by the need for privacy-respecting browser-based tools
|
|
266
|
+
|
|
267
|
+
**Questions?** Open an [issue](../../issues) or check the [documentation](https://wip-docs.vercel.app).
|
package/package.json
CHANGED
|
@@ -1,45 +1,135 @@
|
|
|
1
1
|
/* tslint:disable */
|
|
2
2
|
/* eslint-disable */
|
|
3
|
+
|
|
3
4
|
/**
|
|
4
|
-
*
|
|
5
|
+
* Builder-style image processor for JS/Wasm usage.
|
|
6
|
+
*
|
|
7
|
+
* ```javascript
|
|
8
|
+
* // Browser usage (after wasm-bindgen or bundler setup)
|
|
9
|
+
* // const { ImageProcessor } = await init();
|
|
10
|
+
* const input = document.querySelector("#file");
|
|
11
|
+
* const outputImg = document.querySelector("#output");
|
|
12
|
+
*
|
|
13
|
+
* input.addEventListener("change", async (event) => {
|
|
14
|
+
* const file = event.target.files[0];
|
|
15
|
+
* if (!file) return;
|
|
16
|
+
*
|
|
17
|
+
* const inputBytes = new Uint8Array(await file.arrayBuffer());
|
|
18
|
+
* const outputBytes = new ImageProcessor(inputBytes)
|
|
19
|
+
* .resize(512, 512)
|
|
20
|
+
* .grayscale()
|
|
21
|
+
* .contrast(25.0)
|
|
22
|
+
* .process();
|
|
23
|
+
*
|
|
24
|
+
* const blob = new Blob([outputBytes], { type: file.type });
|
|
25
|
+
* outputImg.src = URL.createObjectURL(blob);
|
|
26
|
+
* });
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* ```javascript
|
|
30
|
+
* // Canvas usage (after wasm-bindgen or bundler setup)
|
|
31
|
+
* // const { ImageProcessor } = await init();
|
|
32
|
+
* const input = document.querySelector("#file");
|
|
33
|
+
* const canvas = document.querySelector("#canvas");
|
|
34
|
+
* const ctx = canvas.getContext("2d");
|
|
35
|
+
*
|
|
36
|
+
* input.addEventListener("change", async (event) => {
|
|
37
|
+
* const file = event.target.files[0];
|
|
38
|
+
* if (!file) return;
|
|
39
|
+
*
|
|
40
|
+
* const inputBytes = new Uint8Array(await file.arrayBuffer());
|
|
41
|
+
* const outputBytes = new ImageProcessor(inputBytes)
|
|
42
|
+
* .resize(512, 512)
|
|
43
|
+
* .blur(2.0)
|
|
44
|
+
* .process();
|
|
45
|
+
*
|
|
46
|
+
* const blob = new Blob([outputBytes], { type: file.type });
|
|
47
|
+
* const bitmap = await createImageBitmap(blob);
|
|
48
|
+
* canvas.width = bitmap.width;
|
|
49
|
+
* canvas.height = bitmap.height;
|
|
50
|
+
* ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
51
|
+
* ctx.drawImage(bitmap, 0, 0);
|
|
52
|
+
* });
|
|
53
|
+
* ```
|
|
5
54
|
*/
|
|
6
|
-
export
|
|
55
|
+
export class ImageProcessor {
|
|
56
|
+
private constructor();
|
|
57
|
+
free(): void;
|
|
58
|
+
[Symbol.dispose](): void;
|
|
59
|
+
blur(sigma: number): ImageProcessor;
|
|
60
|
+
brighten(value: number): ImageProcessor;
|
|
61
|
+
contrast(value: number): ImageProcessor;
|
|
62
|
+
crop(x: number, y: number, width: number, height: number): ImageProcessor;
|
|
63
|
+
fast_blur(sigma: number): ImageProcessor;
|
|
64
|
+
grayscale(): ImageProcessor;
|
|
65
|
+
hue_rotate(degrees: number): ImageProcessor;
|
|
66
|
+
invert(): ImageProcessor;
|
|
67
|
+
/**
|
|
68
|
+
* Create a new processor from raw image bytes.
|
|
69
|
+
*/
|
|
70
|
+
static new(image: Uint8Array): ImageProcessor;
|
|
71
|
+
/**
|
|
72
|
+
* Calling this returns the final image bytes.
|
|
73
|
+
*/
|
|
74
|
+
process(): Uint8Array;
|
|
75
|
+
resize(width: number, height: number): ImageProcessor;
|
|
76
|
+
resize_square(side: number): ImageProcessor;
|
|
77
|
+
thumbnail(width: number, height: number): ImageProcessor;
|
|
78
|
+
}
|
|
79
|
+
|
|
7
80
|
/**
|
|
8
|
-
*
|
|
9
|
-
* `
|
|
10
|
-
*
|
|
11
|
-
* just like the css webkit filter hue-rotate(180)
|
|
81
|
+
* Performs a Gaussian blur on this image.
|
|
82
|
+
* `sigma` is a measure of how much to blur by.
|
|
83
|
+
* Use a value of less than 5
|
|
12
84
|
*/
|
|
13
|
-
export function
|
|
85
|
+
export function blur(image_data: Uint8Array, sigma: number): Uint8Array;
|
|
86
|
+
|
|
14
87
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* The image is scaled to the maximum possible size that fits
|
|
18
|
-
* within the bounds specified by `nwidth` and `nheight`.
|
|
19
|
-
*
|
|
20
|
-
* This method uses a fast integer algorithm where each source
|
|
21
|
-
* pixel contributes to exactly one target pixel.
|
|
22
|
-
* May give aliasing artifacts if new size is close to old size.
|
|
88
|
+
* Brighten image
|
|
89
|
+
* The value is -100 to 100
|
|
23
90
|
*/
|
|
24
|
-
export function
|
|
91
|
+
export function brighten(image_data: Uint8Array, value: number): Uint8Array;
|
|
92
|
+
|
|
25
93
|
/**
|
|
26
94
|
* Adjust the contrast of this image.
|
|
27
95
|
* `contrast` is the amount to adjust the contrast by.
|
|
28
96
|
* Negative values decrease the contrast and positive values increase the contrast.
|
|
29
97
|
*/
|
|
30
98
|
export function contrast(image_data: Uint8Array, value: number): Uint8Array;
|
|
99
|
+
|
|
31
100
|
/**
|
|
32
|
-
*
|
|
33
|
-
* `sigma` is a measure of how much to blur by.
|
|
34
|
-
* Use a value of less than 5
|
|
101
|
+
* Return a cut-out of this image delimited by the bounding rectangle.
|
|
35
102
|
*/
|
|
36
|
-
export function
|
|
103
|
+
export function crop(image_data: Uint8Array, x: number, y: number, width: number, height: number): Uint8Array;
|
|
104
|
+
|
|
37
105
|
/**
|
|
38
106
|
* Performs a fast blur on this image.
|
|
39
107
|
* `sigma` is the standard deviation of the
|
|
40
108
|
* (approximated) Gaussian
|
|
41
109
|
*/
|
|
42
110
|
export function fast_blur(image_data: Uint8Array, sigma: number): Uint8Array;
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Add grayscale effect to image
|
|
114
|
+
* Return a grayscale version of this image.
|
|
115
|
+
* Returns `Luma` images in most cases. However, for `f32` images,
|
|
116
|
+
* this will return a grayscale `Rgb/Rgba` image instead.
|
|
117
|
+
*/
|
|
118
|
+
export function grayscale(image_data: Uint8Array): Uint8Array;
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Hue rotate the supplied image.
|
|
122
|
+
* `value` is the degrees to rotate each pixel by.
|
|
123
|
+
* 0 and 360 do nothing, the rest rotates by the given degree value.
|
|
124
|
+
* just like the css webkit filter hue-rotate(180)
|
|
125
|
+
*/
|
|
126
|
+
export function hue_rotate(image_data: Uint8Array, degrees: number): Uint8Array;
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Invert the colors on this image.
|
|
130
|
+
*/
|
|
131
|
+
export function invert(image_data: Uint8Array): Uint8Array;
|
|
132
|
+
|
|
43
133
|
/**
|
|
44
134
|
* Resize an image
|
|
45
135
|
* Take an array of bytes, the len and the width
|
|
@@ -48,17 +138,7 @@ export function fast_blur(image_data: Uint8Array, sigma: number): Uint8Array;
|
|
|
48
138
|
* within the bounds specified by `width` and `height`
|
|
49
139
|
*/
|
|
50
140
|
export function resize(image_data: Uint8Array, width: number, height: number): Uint8Array;
|
|
51
|
-
|
|
52
|
-
* Return a cut-out of this image delimited by the bounding rectangle.
|
|
53
|
-
*/
|
|
54
|
-
export function crop(image_data: Uint8Array, x: number, y: number, width: number, height: number): Uint8Array;
|
|
55
|
-
/**
|
|
56
|
-
* Add grayscale effect to image
|
|
57
|
-
* Return a grayscale version of this image.
|
|
58
|
-
* Returns `Luma` images in most cases. However, for `f32` images,
|
|
59
|
-
* this will return a grayscale `Rgb/Rgba` image instead.
|
|
60
|
-
*/
|
|
61
|
-
export function grayscale(image_data: Uint8Array): Uint8Array;
|
|
141
|
+
|
|
62
142
|
/**
|
|
63
143
|
* Resize an image by the given dimension.
|
|
64
144
|
* The first parameter is an array of bytes.
|
|
@@ -68,8 +148,15 @@ export function grayscale(image_data: Uint8Array): Uint8Array;
|
|
|
68
148
|
* It is is ideal for icon resizing.
|
|
69
149
|
*/
|
|
70
150
|
export function resize_square(image_data: Uint8Array, side: number): Uint8Array;
|
|
151
|
+
|
|
71
152
|
/**
|
|
72
|
-
*
|
|
73
|
-
* The
|
|
153
|
+
* Scale this image down to fit within a specific size.
|
|
154
|
+
* Returns a new image. The image's aspect ratio is preserved.
|
|
155
|
+
* The image is scaled to the maximum possible size that fits
|
|
156
|
+
* within the bounds specified by `nwidth` and `nheight`.
|
|
157
|
+
*
|
|
158
|
+
* This method uses a fast integer algorithm where each source
|
|
159
|
+
* pixel contributes to exactly one target pixel.
|
|
160
|
+
* May give aliasing artifacts if new size is close to old size.
|
|
74
161
|
*/
|
|
75
|
-
export function
|
|
162
|
+
export function thumbnail(image_data: Uint8Array, width: number, height: number): Uint8Array;
|
package/wasm_image_processor.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
/* @ts-self-types="./wasm_image_processor.d.ts" */
|
|
2
|
+
|
|
1
3
|
import * as wasm from "./wasm_image_processor_bg.wasm";
|
|
2
|
-
export * from "./wasm_image_processor_bg.js";
|
|
3
4
|
import { __wbg_set_wasm } from "./wasm_image_processor_bg.js";
|
|
4
5
|
__wbg_set_wasm(wasm);
|
|
5
6
|
wasm.__wbindgen_start();
|
|
7
|
+
export {
|
|
8
|
+
ImageProcessor, blur, brighten, contrast, crop, fast_blur, grayscale, hue_rotate, invert, resize, resize_square, thumbnail
|
|
9
|
+
} from "./wasm_image_processor_bg.js";
|
|
@@ -1,57 +1,244 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Builder-style image processor for JS/Wasm usage.
|
|
3
|
+
*
|
|
4
|
+
* ```javascript
|
|
5
|
+
* // Browser usage (after wasm-bindgen or bundler setup)
|
|
6
|
+
* // const { ImageProcessor } = await init();
|
|
7
|
+
* const input = document.querySelector("#file");
|
|
8
|
+
* const outputImg = document.querySelector("#output");
|
|
9
|
+
*
|
|
10
|
+
* input.addEventListener("change", async (event) => {
|
|
11
|
+
* const file = event.target.files[0];
|
|
12
|
+
* if (!file) return;
|
|
13
|
+
*
|
|
14
|
+
* const inputBytes = new Uint8Array(await file.arrayBuffer());
|
|
15
|
+
* const outputBytes = new ImageProcessor(inputBytes)
|
|
16
|
+
* .resize(512, 512)
|
|
17
|
+
* .grayscale()
|
|
18
|
+
* .contrast(25.0)
|
|
19
|
+
* .process();
|
|
20
|
+
*
|
|
21
|
+
* const blob = new Blob([outputBytes], { type: file.type });
|
|
22
|
+
* outputImg.src = URL.createObjectURL(blob);
|
|
23
|
+
* });
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* ```javascript
|
|
27
|
+
* // Canvas usage (after wasm-bindgen or bundler setup)
|
|
28
|
+
* // const { ImageProcessor } = await init();
|
|
29
|
+
* const input = document.querySelector("#file");
|
|
30
|
+
* const canvas = document.querySelector("#canvas");
|
|
31
|
+
* const ctx = canvas.getContext("2d");
|
|
32
|
+
*
|
|
33
|
+
* input.addEventListener("change", async (event) => {
|
|
34
|
+
* const file = event.target.files[0];
|
|
35
|
+
* if (!file) return;
|
|
36
|
+
*
|
|
37
|
+
* const inputBytes = new Uint8Array(await file.arrayBuffer());
|
|
38
|
+
* const outputBytes = new ImageProcessor(inputBytes)
|
|
39
|
+
* .resize(512, 512)
|
|
40
|
+
* .blur(2.0)
|
|
41
|
+
* .process();
|
|
42
|
+
*
|
|
43
|
+
* const blob = new Blob([outputBytes], { type: file.type });
|
|
44
|
+
* const bitmap = await createImageBitmap(blob);
|
|
45
|
+
* canvas.width = bitmap.width;
|
|
46
|
+
* canvas.height = bitmap.height;
|
|
47
|
+
* ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
48
|
+
* ctx.drawImage(bitmap, 0, 0);
|
|
49
|
+
* });
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
export class ImageProcessor {
|
|
53
|
+
static __wrap(ptr) {
|
|
54
|
+
ptr = ptr >>> 0;
|
|
55
|
+
const obj = Object.create(ImageProcessor.prototype);
|
|
56
|
+
obj.__wbg_ptr = ptr;
|
|
57
|
+
ImageProcessorFinalization.register(obj, obj.__wbg_ptr, obj);
|
|
58
|
+
return obj;
|
|
59
|
+
}
|
|
60
|
+
__destroy_into_raw() {
|
|
61
|
+
const ptr = this.__wbg_ptr;
|
|
62
|
+
this.__wbg_ptr = 0;
|
|
63
|
+
ImageProcessorFinalization.unregister(this);
|
|
64
|
+
return ptr;
|
|
65
|
+
}
|
|
66
|
+
free() {
|
|
67
|
+
const ptr = this.__destroy_into_raw();
|
|
68
|
+
wasm.__wbg_imageprocessor_free(ptr, 0);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* @param {number} sigma
|
|
72
|
+
* @returns {ImageProcessor}
|
|
73
|
+
*/
|
|
74
|
+
blur(sigma) {
|
|
75
|
+
const ptr = this.__destroy_into_raw();
|
|
76
|
+
const ret = wasm.imageprocessor_blur(ptr, sigma);
|
|
77
|
+
if (ret[2]) {
|
|
78
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
79
|
+
}
|
|
80
|
+
return ImageProcessor.__wrap(ret[0]);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* @param {number} value
|
|
84
|
+
* @returns {ImageProcessor}
|
|
85
|
+
*/
|
|
86
|
+
brighten(value) {
|
|
87
|
+
const ptr = this.__destroy_into_raw();
|
|
88
|
+
const ret = wasm.imageprocessor_brighten(ptr, value);
|
|
89
|
+
if (ret[2]) {
|
|
90
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
91
|
+
}
|
|
92
|
+
return ImageProcessor.__wrap(ret[0]);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* @param {number} value
|
|
96
|
+
* @returns {ImageProcessor}
|
|
97
|
+
*/
|
|
98
|
+
contrast(value) {
|
|
99
|
+
const ptr = this.__destroy_into_raw();
|
|
100
|
+
const ret = wasm.imageprocessor_contrast(ptr, value);
|
|
101
|
+
if (ret[2]) {
|
|
102
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
103
|
+
}
|
|
104
|
+
return ImageProcessor.__wrap(ret[0]);
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* @param {number} x
|
|
108
|
+
* @param {number} y
|
|
109
|
+
* @param {number} width
|
|
110
|
+
* @param {number} height
|
|
111
|
+
* @returns {ImageProcessor}
|
|
112
|
+
*/
|
|
113
|
+
crop(x, y, width, height) {
|
|
114
|
+
const ptr = this.__destroy_into_raw();
|
|
115
|
+
const ret = wasm.imageprocessor_crop(ptr, x, y, width, height);
|
|
116
|
+
if (ret[2]) {
|
|
117
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
118
|
+
}
|
|
119
|
+
return ImageProcessor.__wrap(ret[0]);
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* @param {number} sigma
|
|
123
|
+
* @returns {ImageProcessor}
|
|
124
|
+
*/
|
|
125
|
+
fast_blur(sigma) {
|
|
126
|
+
const ptr = this.__destroy_into_raw();
|
|
127
|
+
const ret = wasm.imageprocessor_fast_blur(ptr, sigma);
|
|
128
|
+
if (ret[2]) {
|
|
129
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
130
|
+
}
|
|
131
|
+
return ImageProcessor.__wrap(ret[0]);
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* @returns {ImageProcessor}
|
|
135
|
+
*/
|
|
136
|
+
grayscale() {
|
|
137
|
+
const ptr = this.__destroy_into_raw();
|
|
138
|
+
const ret = wasm.imageprocessor_grayscale(ptr);
|
|
139
|
+
if (ret[2]) {
|
|
140
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
141
|
+
}
|
|
142
|
+
return ImageProcessor.__wrap(ret[0]);
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* @param {number} degrees
|
|
146
|
+
* @returns {ImageProcessor}
|
|
147
|
+
*/
|
|
148
|
+
hue_rotate(degrees) {
|
|
149
|
+
const ptr = this.__destroy_into_raw();
|
|
150
|
+
const ret = wasm.imageprocessor_hue_rotate(ptr, degrees);
|
|
151
|
+
if (ret[2]) {
|
|
152
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
153
|
+
}
|
|
154
|
+
return ImageProcessor.__wrap(ret[0]);
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* @returns {ImageProcessor}
|
|
158
|
+
*/
|
|
159
|
+
invert() {
|
|
160
|
+
const ptr = this.__destroy_into_raw();
|
|
161
|
+
const ret = wasm.imageprocessor_invert(ptr);
|
|
162
|
+
if (ret[2]) {
|
|
163
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
164
|
+
}
|
|
165
|
+
return ImageProcessor.__wrap(ret[0]);
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Create a new processor from raw image bytes.
|
|
169
|
+
* @param {Uint8Array} image
|
|
170
|
+
* @returns {ImageProcessor}
|
|
171
|
+
*/
|
|
172
|
+
static new(image) {
|
|
173
|
+
const ptr0 = passArray8ToWasm0(image, wasm.__wbindgen_malloc);
|
|
174
|
+
const len0 = WASM_VECTOR_LEN;
|
|
175
|
+
const ret = wasm.imageprocessor_new(ptr0, len0);
|
|
176
|
+
return ImageProcessor.__wrap(ret);
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Calling this returns the final image bytes.
|
|
180
|
+
* @returns {Uint8Array}
|
|
181
|
+
*/
|
|
182
|
+
process() {
|
|
183
|
+
const ptr = this.__destroy_into_raw();
|
|
184
|
+
const ret = wasm.imageprocessor_process(ptr);
|
|
185
|
+
var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
|
|
186
|
+
wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
|
|
187
|
+
return v1;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* @param {number} width
|
|
191
|
+
* @param {number} height
|
|
192
|
+
* @returns {ImageProcessor}
|
|
193
|
+
*/
|
|
194
|
+
resize(width, height) {
|
|
195
|
+
const ptr = this.__destroy_into_raw();
|
|
196
|
+
const ret = wasm.imageprocessor_resize(ptr, width, height);
|
|
197
|
+
if (ret[2]) {
|
|
198
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
199
|
+
}
|
|
200
|
+
return ImageProcessor.__wrap(ret[0]);
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* @param {number} side
|
|
204
|
+
* @returns {ImageProcessor}
|
|
205
|
+
*/
|
|
206
|
+
resize_square(side) {
|
|
207
|
+
const ptr = this.__destroy_into_raw();
|
|
208
|
+
const ret = wasm.imageprocessor_resize_square(ptr, side);
|
|
209
|
+
if (ret[2]) {
|
|
210
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
211
|
+
}
|
|
212
|
+
return ImageProcessor.__wrap(ret[0]);
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* @param {number} width
|
|
216
|
+
* @param {number} height
|
|
217
|
+
* @returns {ImageProcessor}
|
|
218
|
+
*/
|
|
219
|
+
thumbnail(width, height) {
|
|
220
|
+
const ptr = this.__destroy_into_raw();
|
|
221
|
+
const ret = wasm.imageprocessor_thumbnail(ptr, width, height);
|
|
222
|
+
if (ret[2]) {
|
|
223
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
224
|
+
}
|
|
225
|
+
return ImageProcessor.__wrap(ret[0]);
|
|
18
226
|
}
|
|
19
|
-
return cachedUint8ArrayMemory0;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function getStringFromWasm0(ptr, len) {
|
|
23
|
-
ptr = ptr >>> 0;
|
|
24
|
-
return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
let WASM_VECTOR_LEN = 0;
|
|
28
|
-
|
|
29
|
-
function passArray8ToWasm0(arg, malloc) {
|
|
30
|
-
const ptr = malloc(arg.length * 1, 1) >>> 0;
|
|
31
|
-
getUint8ArrayMemory0().set(arg, ptr / 1);
|
|
32
|
-
WASM_VECTOR_LEN = arg.length;
|
|
33
|
-
return ptr;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function takeFromExternrefTable0(idx) {
|
|
37
|
-
const value = wasm.__wbindgen_export_0.get(idx);
|
|
38
|
-
wasm.__externref_table_dealloc(idx);
|
|
39
|
-
return value;
|
|
40
227
|
}
|
|
228
|
+
if (Symbol.dispose) ImageProcessor.prototype[Symbol.dispose] = ImageProcessor.prototype.free;
|
|
41
229
|
|
|
42
|
-
function getArrayU8FromWasm0(ptr, len) {
|
|
43
|
-
ptr = ptr >>> 0;
|
|
44
|
-
return getUint8ArrayMemory0().subarray(ptr / 1, ptr / 1 + len);
|
|
45
|
-
}
|
|
46
230
|
/**
|
|
47
|
-
*
|
|
231
|
+
* Performs a Gaussian blur on this image.
|
|
232
|
+
* `sigma` is a measure of how much to blur by.
|
|
233
|
+
* Use a value of less than 5
|
|
48
234
|
* @param {Uint8Array} image_data
|
|
235
|
+
* @param {number} sigma
|
|
49
236
|
* @returns {Uint8Array}
|
|
50
237
|
*/
|
|
51
|
-
export function
|
|
238
|
+
export function blur(image_data, sigma) {
|
|
52
239
|
const ptr0 = passArray8ToWasm0(image_data, wasm.__wbindgen_malloc);
|
|
53
240
|
const len0 = WASM_VECTOR_LEN;
|
|
54
|
-
const ret = wasm.
|
|
241
|
+
const ret = wasm.blur(ptr0, len0, sigma);
|
|
55
242
|
if (ret[3]) {
|
|
56
243
|
throw takeFromExternrefTable0(ret[2]);
|
|
57
244
|
}
|
|
@@ -61,18 +248,16 @@ export function invert(image_data) {
|
|
|
61
248
|
}
|
|
62
249
|
|
|
63
250
|
/**
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
* 0 and 360 do nothing, the rest rotates by the given degree value.
|
|
67
|
-
* just like the css webkit filter hue-rotate(180)
|
|
251
|
+
* Brighten image
|
|
252
|
+
* The value is -100 to 100
|
|
68
253
|
* @param {Uint8Array} image_data
|
|
69
|
-
* @param {number}
|
|
254
|
+
* @param {number} value
|
|
70
255
|
* @returns {Uint8Array}
|
|
71
256
|
*/
|
|
72
|
-
export function
|
|
257
|
+
export function brighten(image_data, value) {
|
|
73
258
|
const ptr0 = passArray8ToWasm0(image_data, wasm.__wbindgen_malloc);
|
|
74
259
|
const len0 = WASM_VECTOR_LEN;
|
|
75
|
-
const ret = wasm.
|
|
260
|
+
const ret = wasm.brighten(ptr0, len0, value);
|
|
76
261
|
if (ret[3]) {
|
|
77
262
|
throw takeFromExternrefTable0(ret[2]);
|
|
78
263
|
}
|
|
@@ -82,23 +267,17 @@ export function hue_rotate(image_data, degrees) {
|
|
|
82
267
|
}
|
|
83
268
|
|
|
84
269
|
/**
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
* within the bounds specified by `nwidth` and `nheight`.
|
|
89
|
-
*
|
|
90
|
-
* This method uses a fast integer algorithm where each source
|
|
91
|
-
* pixel contributes to exactly one target pixel.
|
|
92
|
-
* May give aliasing artifacts if new size is close to old size.
|
|
270
|
+
* Adjust the contrast of this image.
|
|
271
|
+
* `contrast` is the amount to adjust the contrast by.
|
|
272
|
+
* Negative values decrease the contrast and positive values increase the contrast.
|
|
93
273
|
* @param {Uint8Array} image_data
|
|
94
|
-
* @param {number}
|
|
95
|
-
* @param {number} height
|
|
274
|
+
* @param {number} value
|
|
96
275
|
* @returns {Uint8Array}
|
|
97
276
|
*/
|
|
98
|
-
export function
|
|
277
|
+
export function contrast(image_data, value) {
|
|
99
278
|
const ptr0 = passArray8ToWasm0(image_data, wasm.__wbindgen_malloc);
|
|
100
279
|
const len0 = WASM_VECTOR_LEN;
|
|
101
|
-
const ret = wasm.
|
|
280
|
+
const ret = wasm.contrast(ptr0, len0, value);
|
|
102
281
|
if (ret[3]) {
|
|
103
282
|
throw takeFromExternrefTable0(ret[2]);
|
|
104
283
|
}
|
|
@@ -108,17 +287,18 @@ export function thumbnail(image_data, width, height) {
|
|
|
108
287
|
}
|
|
109
288
|
|
|
110
289
|
/**
|
|
111
|
-
*
|
|
112
|
-
* `contrast` is the amount to adjust the contrast by.
|
|
113
|
-
* Negative values decrease the contrast and positive values increase the contrast.
|
|
290
|
+
* Return a cut-out of this image delimited by the bounding rectangle.
|
|
114
291
|
* @param {Uint8Array} image_data
|
|
115
|
-
* @param {number}
|
|
292
|
+
* @param {number} x
|
|
293
|
+
* @param {number} y
|
|
294
|
+
* @param {number} width
|
|
295
|
+
* @param {number} height
|
|
116
296
|
* @returns {Uint8Array}
|
|
117
297
|
*/
|
|
118
|
-
export function
|
|
298
|
+
export function crop(image_data, x, y, width, height) {
|
|
119
299
|
const ptr0 = passArray8ToWasm0(image_data, wasm.__wbindgen_malloc);
|
|
120
300
|
const len0 = WASM_VECTOR_LEN;
|
|
121
|
-
const ret = wasm.
|
|
301
|
+
const ret = wasm.crop(ptr0, len0, x, y, width, height);
|
|
122
302
|
if (ret[3]) {
|
|
123
303
|
throw takeFromExternrefTable0(ret[2]);
|
|
124
304
|
}
|
|
@@ -128,17 +308,17 @@ export function contrast(image_data, value) {
|
|
|
128
308
|
}
|
|
129
309
|
|
|
130
310
|
/**
|
|
131
|
-
* Performs a
|
|
132
|
-
* `sigma` is
|
|
133
|
-
*
|
|
311
|
+
* Performs a fast blur on this image.
|
|
312
|
+
* `sigma` is the standard deviation of the
|
|
313
|
+
* (approximated) Gaussian
|
|
134
314
|
* @param {Uint8Array} image_data
|
|
135
315
|
* @param {number} sigma
|
|
136
316
|
* @returns {Uint8Array}
|
|
137
317
|
*/
|
|
138
|
-
export function
|
|
318
|
+
export function fast_blur(image_data, sigma) {
|
|
139
319
|
const ptr0 = passArray8ToWasm0(image_data, wasm.__wbindgen_malloc);
|
|
140
320
|
const len0 = WASM_VECTOR_LEN;
|
|
141
|
-
const ret = wasm.
|
|
321
|
+
const ret = wasm.fast_blur(ptr0, len0, sigma);
|
|
142
322
|
if (ret[3]) {
|
|
143
323
|
throw takeFromExternrefTable0(ret[2]);
|
|
144
324
|
}
|
|
@@ -148,17 +328,17 @@ export function blur(image_data, sigma) {
|
|
|
148
328
|
}
|
|
149
329
|
|
|
150
330
|
/**
|
|
151
|
-
*
|
|
152
|
-
*
|
|
153
|
-
*
|
|
331
|
+
* Add grayscale effect to image
|
|
332
|
+
* Return a grayscale version of this image.
|
|
333
|
+
* Returns `Luma` images in most cases. However, for `f32` images,
|
|
334
|
+
* this will return a grayscale `Rgb/Rgba` image instead.
|
|
154
335
|
* @param {Uint8Array} image_data
|
|
155
|
-
* @param {number} sigma
|
|
156
336
|
* @returns {Uint8Array}
|
|
157
337
|
*/
|
|
158
|
-
export function
|
|
338
|
+
export function grayscale(image_data) {
|
|
159
339
|
const ptr0 = passArray8ToWasm0(image_data, wasm.__wbindgen_malloc);
|
|
160
340
|
const len0 = WASM_VECTOR_LEN;
|
|
161
|
-
const ret = wasm.
|
|
341
|
+
const ret = wasm.grayscale(ptr0, len0);
|
|
162
342
|
if (ret[3]) {
|
|
163
343
|
throw takeFromExternrefTable0(ret[2]);
|
|
164
344
|
}
|
|
@@ -168,20 +348,18 @@ export function fast_blur(image_data, sigma) {
|
|
|
168
348
|
}
|
|
169
349
|
|
|
170
350
|
/**
|
|
171
|
-
*
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
*
|
|
175
|
-
* within the bounds specified by `width` and `height`
|
|
351
|
+
* Hue rotate the supplied image.
|
|
352
|
+
* `value` is the degrees to rotate each pixel by.
|
|
353
|
+
* 0 and 360 do nothing, the rest rotates by the given degree value.
|
|
354
|
+
* just like the css webkit filter hue-rotate(180)
|
|
176
355
|
* @param {Uint8Array} image_data
|
|
177
|
-
* @param {number}
|
|
178
|
-
* @param {number} height
|
|
356
|
+
* @param {number} degrees
|
|
179
357
|
* @returns {Uint8Array}
|
|
180
358
|
*/
|
|
181
|
-
export function
|
|
359
|
+
export function hue_rotate(image_data, degrees) {
|
|
182
360
|
const ptr0 = passArray8ToWasm0(image_data, wasm.__wbindgen_malloc);
|
|
183
361
|
const len0 = WASM_VECTOR_LEN;
|
|
184
|
-
const ret = wasm.
|
|
362
|
+
const ret = wasm.hue_rotate(ptr0, len0, degrees);
|
|
185
363
|
if (ret[3]) {
|
|
186
364
|
throw takeFromExternrefTable0(ret[2]);
|
|
187
365
|
}
|
|
@@ -191,18 +369,14 @@ export function resize(image_data, width, height) {
|
|
|
191
369
|
}
|
|
192
370
|
|
|
193
371
|
/**
|
|
194
|
-
*
|
|
372
|
+
* Invert the colors on this image.
|
|
195
373
|
* @param {Uint8Array} image_data
|
|
196
|
-
* @param {number} x
|
|
197
|
-
* @param {number} y
|
|
198
|
-
* @param {number} width
|
|
199
|
-
* @param {number} height
|
|
200
374
|
* @returns {Uint8Array}
|
|
201
375
|
*/
|
|
202
|
-
export function
|
|
376
|
+
export function invert(image_data) {
|
|
203
377
|
const ptr0 = passArray8ToWasm0(image_data, wasm.__wbindgen_malloc);
|
|
204
378
|
const len0 = WASM_VECTOR_LEN;
|
|
205
|
-
const ret = wasm.
|
|
379
|
+
const ret = wasm.invert(ptr0, len0);
|
|
206
380
|
if (ret[3]) {
|
|
207
381
|
throw takeFromExternrefTable0(ret[2]);
|
|
208
382
|
}
|
|
@@ -212,17 +386,20 @@ export function crop(image_data, x, y, width, height) {
|
|
|
212
386
|
}
|
|
213
387
|
|
|
214
388
|
/**
|
|
215
|
-
*
|
|
216
|
-
*
|
|
217
|
-
*
|
|
218
|
-
*
|
|
389
|
+
* Resize an image
|
|
390
|
+
* Take an array of bytes, the len and the width
|
|
391
|
+
* The image's aspect ratio is preserved.
|
|
392
|
+
* The image is scaled to the maximum possible size that fits
|
|
393
|
+
* within the bounds specified by `width` and `height`
|
|
219
394
|
* @param {Uint8Array} image_data
|
|
395
|
+
* @param {number} width
|
|
396
|
+
* @param {number} height
|
|
220
397
|
* @returns {Uint8Array}
|
|
221
398
|
*/
|
|
222
|
-
export function
|
|
399
|
+
export function resize(image_data, width, height) {
|
|
223
400
|
const ptr0 = passArray8ToWasm0(image_data, wasm.__wbindgen_malloc);
|
|
224
401
|
const len0 = WASM_VECTOR_LEN;
|
|
225
|
-
const ret = wasm.
|
|
402
|
+
const ret = wasm.resize(ptr0, len0, width, height);
|
|
226
403
|
if (ret[3]) {
|
|
227
404
|
throw takeFromExternrefTable0(ret[2]);
|
|
228
405
|
}
|
|
@@ -255,16 +432,23 @@ export function resize_square(image_data, side) {
|
|
|
255
432
|
}
|
|
256
433
|
|
|
257
434
|
/**
|
|
258
|
-
*
|
|
259
|
-
* The
|
|
435
|
+
* Scale this image down to fit within a specific size.
|
|
436
|
+
* Returns a new image. The image's aspect ratio is preserved.
|
|
437
|
+
* The image is scaled to the maximum possible size that fits
|
|
438
|
+
* within the bounds specified by `nwidth` and `nheight`.
|
|
439
|
+
*
|
|
440
|
+
* This method uses a fast integer algorithm where each source
|
|
441
|
+
* pixel contributes to exactly one target pixel.
|
|
442
|
+
* May give aliasing artifacts if new size is close to old size.
|
|
260
443
|
* @param {Uint8Array} image_data
|
|
261
|
-
* @param {number}
|
|
444
|
+
* @param {number} width
|
|
445
|
+
* @param {number} height
|
|
262
446
|
* @returns {Uint8Array}
|
|
263
447
|
*/
|
|
264
|
-
export function
|
|
448
|
+
export function thumbnail(image_data, width, height) {
|
|
265
449
|
const ptr0 = passArray8ToWasm0(image_data, wasm.__wbindgen_malloc);
|
|
266
450
|
const len0 = WASM_VECTOR_LEN;
|
|
267
|
-
const ret = wasm.
|
|
451
|
+
const ret = wasm.thumbnail(ptr0, len0, width, height);
|
|
268
452
|
if (ret[3]) {
|
|
269
453
|
throw takeFromExternrefTable0(ret[2]);
|
|
270
454
|
}
|
|
@@ -272,20 +456,150 @@ export function brighten(image_data, value) {
|
|
|
272
456
|
wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
|
|
273
457
|
return v2;
|
|
274
458
|
}
|
|
275
|
-
|
|
459
|
+
export function __wbg_Error_8c4e43fe74559d73(arg0, arg1) {
|
|
460
|
+
const ret = Error(getStringFromWasm0(arg0, arg1));
|
|
461
|
+
return ret;
|
|
462
|
+
}
|
|
463
|
+
export function __wbg___wbindgen_string_get_72fb696202c56729(arg0, arg1) {
|
|
464
|
+
const obj = arg1;
|
|
465
|
+
const ret = typeof(obj) === 'string' ? obj : undefined;
|
|
466
|
+
var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
467
|
+
var len1 = WASM_VECTOR_LEN;
|
|
468
|
+
getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
|
|
469
|
+
getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
|
|
470
|
+
}
|
|
471
|
+
export function __wbg___wbindgen_throw_be289d5034ed271b(arg0, arg1) {
|
|
472
|
+
throw new Error(getStringFromWasm0(arg0, arg1));
|
|
473
|
+
}
|
|
474
|
+
export function __wbindgen_cast_0000000000000001(arg0, arg1) {
|
|
475
|
+
// Cast intrinsic for `Ref(String) -> Externref`.
|
|
476
|
+
const ret = getStringFromWasm0(arg0, arg1);
|
|
477
|
+
return ret;
|
|
478
|
+
}
|
|
276
479
|
export function __wbindgen_init_externref_table() {
|
|
277
|
-
const table = wasm.
|
|
480
|
+
const table = wasm.__wbindgen_externrefs;
|
|
278
481
|
const offset = table.grow(4);
|
|
279
482
|
table.set(0, undefined);
|
|
280
483
|
table.set(offset + 0, undefined);
|
|
281
484
|
table.set(offset + 1, null);
|
|
282
485
|
table.set(offset + 2, true);
|
|
283
486
|
table.set(offset + 3, false);
|
|
284
|
-
|
|
285
|
-
|
|
487
|
+
}
|
|
488
|
+
const ImageProcessorFinalization = (typeof FinalizationRegistry === 'undefined')
|
|
489
|
+
? { register: () => {}, unregister: () => {} }
|
|
490
|
+
: new FinalizationRegistry(ptr => wasm.__wbg_imageprocessor_free(ptr >>> 0, 1));
|
|
286
491
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
return
|
|
290
|
-
}
|
|
492
|
+
function getArrayU8FromWasm0(ptr, len) {
|
|
493
|
+
ptr = ptr >>> 0;
|
|
494
|
+
return getUint8ArrayMemory0().subarray(ptr / 1, ptr / 1 + len);
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
let cachedDataViewMemory0 = null;
|
|
498
|
+
function getDataViewMemory0() {
|
|
499
|
+
if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer)) {
|
|
500
|
+
cachedDataViewMemory0 = new DataView(wasm.memory.buffer);
|
|
501
|
+
}
|
|
502
|
+
return cachedDataViewMemory0;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
function getStringFromWasm0(ptr, len) {
|
|
506
|
+
ptr = ptr >>> 0;
|
|
507
|
+
return decodeText(ptr, len);
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
let cachedUint8ArrayMemory0 = null;
|
|
511
|
+
function getUint8ArrayMemory0() {
|
|
512
|
+
if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {
|
|
513
|
+
cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer);
|
|
514
|
+
}
|
|
515
|
+
return cachedUint8ArrayMemory0;
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
function isLikeNone(x) {
|
|
519
|
+
return x === undefined || x === null;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
function passArray8ToWasm0(arg, malloc) {
|
|
523
|
+
const ptr = malloc(arg.length * 1, 1) >>> 0;
|
|
524
|
+
getUint8ArrayMemory0().set(arg, ptr / 1);
|
|
525
|
+
WASM_VECTOR_LEN = arg.length;
|
|
526
|
+
return ptr;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
function passStringToWasm0(arg, malloc, realloc) {
|
|
530
|
+
if (realloc === undefined) {
|
|
531
|
+
const buf = cachedTextEncoder.encode(arg);
|
|
532
|
+
const ptr = malloc(buf.length, 1) >>> 0;
|
|
533
|
+
getUint8ArrayMemory0().subarray(ptr, ptr + buf.length).set(buf);
|
|
534
|
+
WASM_VECTOR_LEN = buf.length;
|
|
535
|
+
return ptr;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
let len = arg.length;
|
|
539
|
+
let ptr = malloc(len, 1) >>> 0;
|
|
540
|
+
|
|
541
|
+
const mem = getUint8ArrayMemory0();
|
|
291
542
|
|
|
543
|
+
let offset = 0;
|
|
544
|
+
|
|
545
|
+
for (; offset < len; offset++) {
|
|
546
|
+
const code = arg.charCodeAt(offset);
|
|
547
|
+
if (code > 0x7F) break;
|
|
548
|
+
mem[ptr + offset] = code;
|
|
549
|
+
}
|
|
550
|
+
if (offset !== len) {
|
|
551
|
+
if (offset !== 0) {
|
|
552
|
+
arg = arg.slice(offset);
|
|
553
|
+
}
|
|
554
|
+
ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0;
|
|
555
|
+
const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len);
|
|
556
|
+
const ret = cachedTextEncoder.encodeInto(arg, view);
|
|
557
|
+
|
|
558
|
+
offset += ret.written;
|
|
559
|
+
ptr = realloc(ptr, len, offset, 1) >>> 0;
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
WASM_VECTOR_LEN = offset;
|
|
563
|
+
return ptr;
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
function takeFromExternrefTable0(idx) {
|
|
567
|
+
const value = wasm.__wbindgen_externrefs.get(idx);
|
|
568
|
+
wasm.__externref_table_dealloc(idx);
|
|
569
|
+
return value;
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
|
|
573
|
+
cachedTextDecoder.decode();
|
|
574
|
+
const MAX_SAFARI_DECODE_BYTES = 2146435072;
|
|
575
|
+
let numBytesDecoded = 0;
|
|
576
|
+
function decodeText(ptr, len) {
|
|
577
|
+
numBytesDecoded += len;
|
|
578
|
+
if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) {
|
|
579
|
+
cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
|
|
580
|
+
cachedTextDecoder.decode();
|
|
581
|
+
numBytesDecoded = len;
|
|
582
|
+
}
|
|
583
|
+
return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
const cachedTextEncoder = new TextEncoder();
|
|
587
|
+
|
|
588
|
+
if (!('encodeInto' in cachedTextEncoder)) {
|
|
589
|
+
cachedTextEncoder.encodeInto = function (arg, view) {
|
|
590
|
+
const buf = cachedTextEncoder.encode(arg);
|
|
591
|
+
view.set(buf);
|
|
592
|
+
return {
|
|
593
|
+
read: arg.length,
|
|
594
|
+
written: buf.length
|
|
595
|
+
};
|
|
596
|
+
};
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
let WASM_VECTOR_LEN = 0;
|
|
600
|
+
|
|
601
|
+
|
|
602
|
+
let wasm;
|
|
603
|
+
export function __wbg_set_wasm(val) {
|
|
604
|
+
wasm = val;
|
|
605
|
+
}
|
|
Binary file
|