wasm-image-processor 0.1.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/LICENSE +21 -0
- package/README.md +195 -0
- package/package.json +34 -0
- package/wasm_image_processor.d.ts +11 -0
- package/wasm_image_processor.js +5 -0
- package/wasm_image_processor_bg.js +59 -0
- package/wasm_image_processor_bg.wasm +0 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Stanley Masinde
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
# WASM Image Processor
|
|
2
|
+
> Process images offline in the Browser.
|
|
3
|
+
|
|
4
|
+
**⚠️ Early Development Notice**: This project is in active development. APIs may change and there is no npm package available yet. Use at your own risk for production applications.
|
|
5
|
+
|
|
6
|
+
A high-performance image processing toolkit built with Rust and WebAssembly. Process images entirely client-side with no server uploads required.
|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- **Offline Processing**: All image operations happen in your browser
|
|
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
|
|
16
|
+
|
|
17
|
+
## Demo
|
|
18
|
+
|
|
19
|
+
Try the live demo at: [https://stanleymasinde.github.io/wasm-image-processor/](https://stanleymasinde.github.io/wasm-image-processor/)
|
|
20
|
+
|
|
21
|
+
- **Basic Resizer**: Resize images to custom dimensions
|
|
22
|
+
- **PWA Icon Generator**: Generate complete icon sets for web apps
|
|
23
|
+
|
|
24
|
+
## Current Features
|
|
25
|
+
|
|
26
|
+
### Image Resizing
|
|
27
|
+
- Resize images to any dimensions up to 5000x5000 pixels
|
|
28
|
+
- Maintain aspect ratio or force specific dimensions
|
|
29
|
+
- High-quality filtering algorithms
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
## Installation
|
|
33
|
+
|
|
34
|
+
**Note**: No npm package is available yet. You need to build from source.
|
|
35
|
+
|
|
36
|
+
### Prerequisites
|
|
37
|
+
|
|
38
|
+
- [Rust](https://rustup.rs/)
|
|
39
|
+
- [wasm-pack](https://rustwasm.github.io/wasm-pack/)
|
|
40
|
+
|
|
41
|
+
### Building
|
|
42
|
+
|
|
43
|
+
1. Clone the repository:
|
|
44
|
+
```bash
|
|
45
|
+
git clone https://github.com/yourusername/wasm-image-processor.git
|
|
46
|
+
cd wasm-image-processor
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
2. Build the WASM package:
|
|
50
|
+
```bash
|
|
51
|
+
wasm-pack build --target web
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
3. Copy files to demo directory:
|
|
55
|
+
```bash
|
|
56
|
+
# Copy JS and WASM files to demo folder
|
|
57
|
+
./prep-demo.sh
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
4. Serve the demo locally:
|
|
61
|
+
```bash
|
|
62
|
+
# Using Node.js
|
|
63
|
+
npx serve .
|
|
64
|
+
|
|
65
|
+
# Or any other static file server
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
5. Open `http://localhost:3000/demo` in your browser
|
|
69
|
+
|
|
70
|
+
### Usage
|
|
71
|
+
|
|
72
|
+
Include the WASM module in your web page:
|
|
73
|
+
|
|
74
|
+
```html
|
|
75
|
+
<script type="module">
|
|
76
|
+
import init, { resize_square } from "./pwa_image_generator.js";
|
|
77
|
+
|
|
78
|
+
init().then(() => {
|
|
79
|
+
// WASM module is ready
|
|
80
|
+
const imageData = new Uint8Array(/* your image data */);
|
|
81
|
+
const resizedBytes = resize_image(Array.from(imageData), 500);
|
|
82
|
+
|
|
83
|
+
// Use resizedBytes as needed
|
|
84
|
+
});
|
|
85
|
+
</script>
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### API Reference
|
|
89
|
+
|
|
90
|
+
#### `resize_image(image_data: Vec<u8>, side: u32) -> Vec<u8>`
|
|
91
|
+
|
|
92
|
+
Resizes an image to a square with the specified side length.
|
|
93
|
+
|
|
94
|
+
**Parameters:**
|
|
95
|
+
- `image_data`: Image data as a byte array
|
|
96
|
+
- `side`: Target width/height in pixels (1-5000)
|
|
97
|
+
|
|
98
|
+
**Returns:**
|
|
99
|
+
- PNG-encoded image data as byte array
|
|
100
|
+
|
|
101
|
+
**Example:**
|
|
102
|
+
```javascript
|
|
103
|
+
const resizedBytes = resize_image(imageBytes, 256);
|
|
104
|
+
const blob = new Blob([new Uint8Array(resizedBytes)], { type: 'image/png' });
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Project Structure
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
wasm-image-processor/
|
|
111
|
+
├── src/
|
|
112
|
+
│ └─- lib.rs # Main Rust library
|
|
113
|
+
├── demo/
|
|
114
|
+
│ ├── index.html # Basic resizer demo
|
|
115
|
+
│ ├── pwa-generator.html # PWA icon generator
|
|
116
|
+
│ ├── pwa_image_generator.js # Generated JS bindings
|
|
117
|
+
│ └── pwa_image_generator_bg.wasm # Generated WASM binary
|
|
118
|
+
├── pkg/ # wasm-pack output
|
|
119
|
+
├── tests/ # Test files
|
|
120
|
+
├── copy_pkg.sh # Build script
|
|
121
|
+
├── Cargo.toml
|
|
122
|
+
└── README.md
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Development
|
|
126
|
+
|
|
127
|
+
### Running Tests
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
# Run Rust tests
|
|
131
|
+
cargo test
|
|
132
|
+
|
|
133
|
+
# Test with sample images
|
|
134
|
+
cargo test test_resize_logic --lib
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Adding New Features
|
|
138
|
+
|
|
139
|
+
The codebase is structured to easily add new image processing functions:
|
|
140
|
+
|
|
141
|
+
1. Add your function to `src/lib.rs`
|
|
142
|
+
2. Mark it with `#[wasm_bindgen]`
|
|
143
|
+
3. Rebuild with `wasm-pack build --target web`
|
|
144
|
+
4. Update the demo pages to use your new function
|
|
145
|
+
|
|
146
|
+
## Roadmap
|
|
147
|
+
|
|
148
|
+
**Near Term:**
|
|
149
|
+
- [ ] Stable API design
|
|
150
|
+
- [ ] npm package publication
|
|
151
|
+
- [ ] Comprehensive documentation
|
|
152
|
+
- [ ] CI/CD pipeline
|
|
153
|
+
|
|
154
|
+
**Future Features:**
|
|
155
|
+
- [ ] Image format conversion (PNG ↔ JPEG ↔ WebP)
|
|
156
|
+
- [ ] Image compression with quality settings
|
|
157
|
+
- [ ] Batch processing for multiple images
|
|
158
|
+
- [ ] Image filters (blur, sharpen, brightness, contrast)
|
|
159
|
+
- [ ] Custom crop functionality
|
|
160
|
+
- [ ] Image rotation and flipping
|
|
161
|
+
- [ ] Metadata preservation and editing
|
|
162
|
+
- [ ] Advanced resizing algorithms
|
|
163
|
+
|
|
164
|
+
## Browser Support
|
|
165
|
+
|
|
166
|
+
- Chrome/Edge 57+
|
|
167
|
+
- Firefox 52+
|
|
168
|
+
- Safari 11+
|
|
169
|
+
- Any browser with WebAssembly support
|
|
170
|
+
|
|
171
|
+
## Performance
|
|
172
|
+
|
|
173
|
+
Processing is done entirely client-side using WebAssembly, providing:
|
|
174
|
+
- **Fast processing**: Near-native performance
|
|
175
|
+
- **Privacy**: Images never leave your device
|
|
176
|
+
- **Offline capability**: Works without internet connection
|
|
177
|
+
- **Scalability**: No server resources required
|
|
178
|
+
|
|
179
|
+
## Contributing
|
|
180
|
+
|
|
181
|
+
1. Fork the repository
|
|
182
|
+
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
|
|
183
|
+
3. Commit your changes (`git commit -m 'Add amazing feature'`)
|
|
184
|
+
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
185
|
+
5. Open a Pull Request
|
|
186
|
+
|
|
187
|
+
## License
|
|
188
|
+
|
|
189
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
190
|
+
|
|
191
|
+
## Acknowledgments
|
|
192
|
+
|
|
193
|
+
- Built with [Rust](https://www.rust-lang.org/) and [wasm-bindgen](https://rustwasm.github.io/wasm-bindgen/)
|
|
194
|
+
- Image processing powered by the [image](https://github.com/image-rs/image) crate
|
|
195
|
+
- Inspired by the need for client-side image processing tools
|
package/package.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "wasm-image-processor",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"collaborators": [
|
|
5
|
+
"Stanley Masinde <hello@stanleymasinde.com>"
|
|
6
|
+
],
|
|
7
|
+
"description": "High-performance client-side image processing toolkit powered by Rust and WebAssembly",
|
|
8
|
+
"version": "0.1.0",
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "https://github.com/StanleyMasinde/wasm-image-processor"
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"wasm_image_processor_bg.wasm",
|
|
16
|
+
"wasm_image_processor.js",
|
|
17
|
+
"wasm_image_processor_bg.js",
|
|
18
|
+
"wasm_image_processor.d.ts"
|
|
19
|
+
],
|
|
20
|
+
"main": "wasm_image_processor.js",
|
|
21
|
+
"homepage": "https://github.com/StanleyMasinde/wasm-image-processor",
|
|
22
|
+
"types": "wasm_image_processor.d.ts",
|
|
23
|
+
"sideEffects": [
|
|
24
|
+
"./wasm_image_processor.js",
|
|
25
|
+
"./snippets/*"
|
|
26
|
+
],
|
|
27
|
+
"keywords": [
|
|
28
|
+
"wasm",
|
|
29
|
+
"image",
|
|
30
|
+
"processing",
|
|
31
|
+
"resize",
|
|
32
|
+
"pwa"
|
|
33
|
+
]
|
|
34
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/* tslint:disable */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
/**
|
|
4
|
+
* Resize an image by the given dimension.
|
|
5
|
+
* The first parameter is an array of bytes.
|
|
6
|
+
* The second parameter is the size of the sides.
|
|
7
|
+
* This function returns square images. It does not respect the aspect
|
|
8
|
+
* Ratio of the photo.
|
|
9
|
+
* It is is ideal for icon resizing.
|
|
10
|
+
*/
|
|
11
|
+
export function resize_square(image_data: Uint8Array, side: number): Uint8Array;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
let wasm;
|
|
2
|
+
export function __wbg_set_wasm(val) {
|
|
3
|
+
wasm = val;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
let cachedUint8ArrayMemory0 = null;
|
|
8
|
+
|
|
9
|
+
function getUint8ArrayMemory0() {
|
|
10
|
+
if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {
|
|
11
|
+
cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer);
|
|
12
|
+
}
|
|
13
|
+
return cachedUint8ArrayMemory0;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
let WASM_VECTOR_LEN = 0;
|
|
17
|
+
|
|
18
|
+
function passArray8ToWasm0(arg, malloc) {
|
|
19
|
+
const ptr = malloc(arg.length * 1, 1) >>> 0;
|
|
20
|
+
getUint8ArrayMemory0().set(arg, ptr / 1);
|
|
21
|
+
WASM_VECTOR_LEN = arg.length;
|
|
22
|
+
return ptr;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function getArrayU8FromWasm0(ptr, len) {
|
|
26
|
+
ptr = ptr >>> 0;
|
|
27
|
+
return getUint8ArrayMemory0().subarray(ptr / 1, ptr / 1 + len);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Resize an image by the given dimension.
|
|
31
|
+
* The first parameter is an array of bytes.
|
|
32
|
+
* The second parameter is the size of the sides.
|
|
33
|
+
* This function returns square images. It does not respect the aspect
|
|
34
|
+
* Ratio of the photo.
|
|
35
|
+
* It is is ideal for icon resizing.
|
|
36
|
+
* @param {Uint8Array} image_data
|
|
37
|
+
* @param {number} side
|
|
38
|
+
* @returns {Uint8Array}
|
|
39
|
+
*/
|
|
40
|
+
export function resize_square(image_data, side) {
|
|
41
|
+
const ptr0 = passArray8ToWasm0(image_data, wasm.__wbindgen_malloc);
|
|
42
|
+
const len0 = WASM_VECTOR_LEN;
|
|
43
|
+
const ret = wasm.resize_square(ptr0, len0, side);
|
|
44
|
+
var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
|
|
45
|
+
wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
|
|
46
|
+
return v2;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function __wbindgen_init_externref_table() {
|
|
50
|
+
const table = wasm.__wbindgen_export_0;
|
|
51
|
+
const offset = table.grow(4);
|
|
52
|
+
table.set(0, undefined);
|
|
53
|
+
table.set(offset + 0, undefined);
|
|
54
|
+
table.set(offset + 1, null);
|
|
55
|
+
table.set(offset + 2, true);
|
|
56
|
+
table.set(offset + 3, false);
|
|
57
|
+
;
|
|
58
|
+
};
|
|
59
|
+
|
|
Binary file
|