image-filter-toolkit 1.0.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 ADDED
@@ -0,0 +1,351 @@
1
+ # Image Filters Package
2
+
3
+ A lightweight JavaScript library for applying various image filters and effects to canvas images. This package provides simple functions for image manipulation including blur, grayscale, inversion, vintage effects, ASCII art generation, and more.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install [your-package-name]
9
+ ```
10
+
11
+ ## Features
12
+
13
+ - 🎨 Multiple image filters (blur, grayscale, inversion, vintage)
14
+ - 🔤 ASCII art generation with color support
15
+ - 🖼️ Image data encoding/decoding utilities
16
+ - 🚀 Easy to use with HTML5 Canvas
17
+ - ⚡ In-place pixel manipulation for performance
18
+
19
+ ## Usage
20
+
21
+ ### Setup
22
+
23
+ First, import the functions you need:
24
+
25
+ ```javascript
26
+ import {
27
+ bLur,
28
+ BW,
29
+ ASCII_generator,
30
+ inversion,
31
+ vintage,
32
+ ImageDataGenerate,
33
+ encodeImageData,
34
+ decodeImageData
35
+ } from '[your-package-name]';
36
+ ```
37
+
38
+ ### Basic Example
39
+
40
+ ```javascript
41
+ // Setup canvas
42
+ const canvas = document.getElementById('myCanvas');
43
+ const ctx = canvas.getContext('2d');
44
+
45
+ // Load an image
46
+ const fileInput = document.getElementById('fileInput');
47
+ fileInput.addEventListener('change', async (e) => {
48
+ const file = e.target.files[0];
49
+
50
+ // Generate image data
51
+ const { width, height } = await ImageDataGenerate(file, canvas, ctx);
52
+
53
+ // Get pixel data
54
+ const imageData = ctx.getImageData(0, 0, width, height);
55
+ const pixels = imageData.data;
56
+
57
+ // Apply a filter
58
+ BW(pixels);
59
+
60
+ // Put modified pixels back to canvas
61
+ ctx.putImageData(imageData, 0, 0);
62
+ });
63
+ ```
64
+
65
+ ## API Reference
66
+
67
+ ### `bLur(pixels)`
68
+
69
+ Applies a blur effect to the image using a 21x21 box blur kernel.
70
+
71
+ **Parameters:**
72
+ - `pixels` (Uint8ClampedArray): The pixel data from canvas ImageData
73
+
74
+ **Example:**
75
+ ```javascript
76
+ const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
77
+ bLur(imageData.data);
78
+ ctx.putImageData(imageData, 0, 0);
79
+ ```
80
+
81
+ ---
82
+
83
+ ### `BW(pixels)`
84
+
85
+ Converts the image to grayscale using average method.
86
+
87
+ **Parameters:**
88
+ - `pixels` (Uint8ClampedArray): The pixel data from canvas ImageData
89
+
90
+ **Example:**
91
+ ```javascript
92
+ const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
93
+ BW(imageData.data);
94
+ ctx.putImageData(imageData, 0, 0);
95
+ ```
96
+
97
+ ---
98
+
99
+ ### `inversion(pixels)`
100
+
101
+ Inverts all colors in the image (negative effect).
102
+
103
+ **Parameters:**
104
+ - `pixels` (Uint8ClampedArray): The pixel data from canvas ImageData
105
+
106
+ **Example:**
107
+ ```javascript
108
+ const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
109
+ inversion(imageData.data);
110
+ ctx.putImageData(imageData, 0, 0);
111
+ ```
112
+
113
+ ---
114
+
115
+ ### `vintage(pixels)`
116
+
117
+ Applies a vintage/sepia tone effect to the image.
118
+
119
+ **Parameters:**
120
+ - `pixels` (Uint8ClampedArray): The pixel data from canvas ImageData
121
+
122
+ **Example:**
123
+ ```javascript
124
+ const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
125
+ vintage(imageData.data);
126
+ ctx.putImageData(imageData, 0, 0);
127
+ ```
128
+
129
+ ---
130
+
131
+ ### `ASCII_generator(pixels, width, options)`
132
+
133
+ Converts an image to ASCII art.
134
+
135
+ **Parameters:**
136
+ - `pixels` (Uint8ClampedArray): The pixel data from canvas ImageData
137
+ - `width` (number): Width of the image
138
+ - `options` (object): Optional configuration
139
+ - `char` (array): Custom ASCII characters (default: `[".", ",", ":", "-", "=", "+", "*", "#", "%", "@"]`)
140
+ - `color` (boolean): Whether to use colored output (default: `true`)
141
+
142
+ **Returns:** String containing HTML with ASCII art
143
+
144
+ **Example:**
145
+ ```javascript
146
+ const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
147
+
148
+ // Basic usage with colors
149
+ const asciiArt = ASCII_generator(imageData.data, canvas.width);
150
+ document.getElementById('output').innerHTML = `<pre>${asciiArt}</pre>`;
151
+
152
+ // Custom characters without color
153
+ const customAscii = ASCII_generator(imageData.data, canvas.width, {
154
+ char: [' ', '.', ':', '-', '=', '+', '*', '#', '@'],
155
+ color: false
156
+ });
157
+ document.getElementById('output').innerHTML = `<pre>${customAscii}</pre>`;
158
+ ```
159
+
160
+ ---
161
+
162
+ ### `ImageDataGenerate(file, canvas, ctx)`
163
+
164
+ Loads an image file and draws it to a canvas.
165
+
166
+ **Parameters:**
167
+ - `file` (File): Image file from input element
168
+ - `canvas` (HTMLCanvasElement): Canvas element
169
+ - `ctx` (CanvasRenderingContext2D): Canvas 2D context
170
+
171
+ **Returns:** Promise resolving to `{width, height}`
172
+
173
+ **Example:**
174
+ ```javascript
175
+ const fileInput = document.getElementById('fileInput');
176
+ const canvas = document.getElementById('canvas');
177
+ const ctx = canvas.getContext('2d');
178
+
179
+ fileInput.addEventListener('change', async (e) => {
180
+ const file = e.target.files[0];
181
+ const { width, height } = await ImageDataGenerate(file, canvas, ctx);
182
+ console.log(`Image loaded: ${width}x${height}`);
183
+ });
184
+ ```
185
+
186
+ ---
187
+
188
+ ### `encodeImageData(imageData, width, height)`
189
+
190
+ Converts ImageData to a 2D array format for easier manipulation.
191
+
192
+ **Parameters:**
193
+ - `imageData` (Uint8ClampedArray): Pixel data
194
+ - `width` (number): Image width
195
+ - `height` (number): Image height
196
+
197
+ **Returns:** 2D array where each element is `[r, g, b, alpha]`
198
+
199
+ **Example:**
200
+ ```javascript
201
+ const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
202
+ const binaryMatrix = encodeImageData(
203
+ imageData.data,
204
+ canvas.width,
205
+ canvas.height
206
+ );
207
+
208
+ // Now you can easily access pixels
209
+ const pixelColor = binaryMatrix[10][20]; // [r, g, b, alpha] at position (20, 10)
210
+ ```
211
+
212
+ ---
213
+
214
+ ### `decodeImageData(binary)`
215
+
216
+ Converts a 2D array format back to ImageData format.
217
+
218
+ **Parameters:**
219
+ - `binary` (array): 2D array where each element is `[r, g, b, alpha]`
220
+
221
+ **Returns:** Object with `{data, width, height}`
222
+
223
+ **Example:**
224
+ ```javascript
225
+ // Create a 2D array (e.g., 100x100 red image)
226
+ const binary = Array(100).fill(0).map(() =>
227
+ Array(100).fill(0).map(() => [255, 0, 0, 255])
228
+ );
229
+
230
+ // Convert to ImageData format
231
+ const { data, width, height } = decodeImageData(binary);
232
+
233
+ // Create ImageData and draw to canvas
234
+ const imageData = new ImageData(data, width, height);
235
+ ctx.putImageData(imageData, 0, 0);
236
+ ```
237
+
238
+ ## Complete Example
239
+
240
+ ```html
241
+ <!DOCTYPE html>
242
+ <html>
243
+ <head>
244
+ <title>Image Filters Demo</title>
245
+ <style>
246
+ canvas { border: 1px solid #ccc; }
247
+ pre { font-family: monospace; line-height: 0.8; font-size: 8px; }
248
+ </style>
249
+ </head>
250
+ <body>
251
+ <input type="file" id="fileInput" accept="image/*">
252
+ <div>
253
+ <button onclick="applyGrayscale()">Grayscale</button>
254
+ <button onclick="applyInvert()">Invert</button>
255
+ <button onclick="applyVintage()">Vintage</button>
256
+ <button onclick="applyBlur()">Blur</button>
257
+ <button onclick="generateASCII()">ASCII Art</button>
258
+ </div>
259
+ <canvas id="canvas"></canvas>
260
+ <div id="ascii-output"></div>
261
+
262
+ <script type="module">
263
+ import {
264
+ bLur, BW, ASCII_generator, inversion, vintage, ImageDataGenerate
265
+ } from '[your-package-name]';
266
+
267
+ const canvas = document.getElementById('canvas');
268
+ const ctx = canvas.getContext('2d');
269
+ let originalImageData;
270
+
271
+ document.getElementById('fileInput').addEventListener('change', async (e) => {
272
+ const file = e.target.files[0];
273
+ await ImageDataGenerate(file, canvas, ctx);
274
+ originalImageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
275
+ });
276
+
277
+ window.applyGrayscale = () => {
278
+ const imageData = new ImageData(
279
+ new Uint8ClampedArray(originalImageData.data),
280
+ originalImageData.width,
281
+ originalImageData.height
282
+ );
283
+ BW(imageData.data);
284
+ ctx.putImageData(imageData, 0, 0);
285
+ };
286
+
287
+ window.applyInvert = () => {
288
+ const imageData = new ImageData(
289
+ new Uint8ClampedArray(originalImageData.data),
290
+ originalImageData.width,
291
+ originalImageData.height
292
+ );
293
+ inversion(imageData.data);
294
+ ctx.putImageData(imageData, 0, 0);
295
+ };
296
+
297
+ window.applyVintage = () => {
298
+ const imageData = new ImageData(
299
+ new Uint8ClampedArray(originalImageData.data),
300
+ originalImageData.width,
301
+ originalImageData.height
302
+ );
303
+ vintage(imageData.data);
304
+ ctx.putImageData(imageData, 0, 0);
305
+ };
306
+
307
+ window.applyBlur = () => {
308
+ const imageData = new ImageData(
309
+ new Uint8ClampedArray(originalImageData.data),
310
+ originalImageData.width,
311
+ originalImageData.height
312
+ );
313
+ bLur(imageData.data);
314
+ ctx.putImageData(imageData, 0, 0);
315
+ };
316
+
317
+ window.generateASCII = () => {
318
+ const ascii = ASCII_generator(
319
+ originalImageData.data,
320
+ originalImageData.width,
321
+ { color: true }
322
+ );
323
+ document.getElementById('ascii-output').innerHTML = `<pre>${ascii}</pre>`;
324
+ };
325
+ </script>
326
+ </body>
327
+ </html>
328
+ ```
329
+
330
+ ## Browser Compatibility
331
+
332
+ This package works in all modern browsers that support:
333
+ - HTML5 Canvas
334
+ - ES6 Modules
335
+ - Uint8ClampedArray
336
+
337
+ ## License
338
+
339
+ MIT
340
+
341
+ ## Contributing
342
+
343
+ Contributions are welcome! Please feel free to submit a Pull Request.
344
+
345
+ ## Author
346
+
347
+ [Your Name]
348
+
349
+ ## Repository
350
+
351
+ [GitHub Repository URL]
package/decoder.js ADDED
@@ -0,0 +1,24 @@
1
+
2
+ export function decodeImageData(binary){
3
+ const height = binary.length
4
+ const width = binary[0].length
5
+ const imageData = new Uint8ClampedArray(width*height*4)
6
+ for(let y=0; y; y++){
7
+ if (binary[y].length !== width) {
8
+ throw new Error("Invalid binary matrix: inconsistent row width");
9
+ }
10
+ for(let x=0; x<SIZE; x++){
11
+ const i = (y*width+x)*4
12
+ const [r, g, b, alpha] = binary[y][x]
13
+ imageData[i] = r
14
+ imageData[i+1] = g
15
+ imageData[i+2] = b
16
+ imageData[i+3] = alpha
17
+ }
18
+ }
19
+ return({
20
+ data:imageData,
21
+ width,
22
+ height
23
+ })
24
+ }
package/encoder.js ADDED
@@ -0,0 +1,22 @@
1
+ export function encodeImageData(imageData, width, height){
2
+ const Binary = []
3
+ for(let y=0; y<height; y++){
4
+ let row = []
5
+ for(let x =0; x<width; x++){
6
+ const i = (y * SIZE + x) * 4;
7
+ const r = imageData[i];
8
+ const g = imageData[i + 1];
9
+ const b = imageData[i + 2];
10
+ const alpha = data[i+3]
11
+ if(alpha<50){
12
+ row.push([0,0,0,0]);
13
+ }else{
14
+ row.push([r,g,b,alpha])
15
+ }
16
+
17
+ }
18
+ Binary.push(row)
19
+ }
20
+ return Binary
21
+
22
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Convert image pixels to grayscale (in-place)
3
+ * @param {Uint8ClampedArray} pixels
4
+ */
5
+ export function BW(pixels){
6
+ for(let i=0; i<=pixels.height; i+=4){
7
+ let r = pixels[i]
8
+ let g = pixels[i+1]
9
+ let b = pixels[i+2]
10
+
11
+ let average = (r+g+b)/3
12
+
13
+ pixels[i] = average
14
+ pixels[i+1] = average
15
+ pixels[i+2] = average
16
+
17
+ }
18
+ }
package/filter/blur.js ADDED
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Convert image pixels to grayscale (in-place)
3
+ * @param {Uint8ClampedArray} pixels
4
+ */
5
+ export function bLur(pixels){
6
+ let copy = new Uint8ClampedArray(pixels)
7
+ for(let y = 1; y<=canvas.height; y++){
8
+ for(let x = 1; x<=canvas.width; x++){
9
+ let r = 0, g = 0, b = 0;
10
+ let count = 0
11
+ for(let ky = -10; ky<=10; ky++){
12
+ for(let kx = -10; kx<=10; kx++){
13
+ let py = y + ky
14
+ let px = x + kx
15
+ let index = (py * canvas.width + px) * 4
16
+ r += copy[index]
17
+ g += copy[index+1]
18
+ b += copy[index+2]
19
+ count += 1
20
+ }
21
+ }
22
+ let i = (y * canvas.width + x)*4
23
+ pixels[i] = r/count
24
+ pixels[i+1] = g/count
25
+ pixels[i+2] = b/count
26
+ }
27
+ }
28
+ }
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Convert image pixels to grayscale (in-place)
3
+ * @param {Uint8ClampedArray} pixels
4
+ */
5
+ export function ASCII_generator(pixels, width, option={}){
6
+ const ASCII_CHARS = option.char||["." , ",", ":", "-", "=", "+","*","#","%", "@"]
7
+ const color = option.color??true
8
+ let asciiHTML = ''
9
+ const height = Math.floor(pixels.length / 4 / width);
10
+ for(let y = 0; y<height; y++){
11
+ for(x =0; x<width; x++){
12
+ let i = (y*width+x)*4
13
+ const r = imageData[i]
14
+ const g = imageData[i+1]
15
+ const b = imageData[i+2]
16
+
17
+ const brightness = 0.299 * r + 0.587 * g + 0.114 * b;
18
+
19
+ const charIndex = Math.floor(
20
+ (brightness / 255) * (ASCII_CHARS.length - 1)
21
+ );
22
+
23
+ const char = ASCII_CHARS[charIndex]
24
+ if(color){
25
+ asciiHTML += `<span style="color:rgb(${r}, ${g}, ${b})">${char}</span>`
26
+ }else{
27
+ asciiHTML += char
28
+ }
29
+
30
+ }
31
+ asciiHTML+='\n'
32
+ }
33
+ return asciiHTML
34
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Convert image pixels to grayscale (in-place)
3
+ * @param {Uint8ClampedArray} pixels
4
+ */
5
+ export function inversion(pixels){
6
+ for (let i = pixels.length - 4; i >= 0; i -= 4) {
7
+ let r = pixels[i];
8
+ let g = pixels[i + 1];
9
+ let b = pixels[i + 2];
10
+
11
+ pixels[i] = 255- r ;
12
+ pixels[i + 1] = 255- g;
13
+ pixels[i + 2] = 255- b ;
14
+ }
15
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Convert image pixels to grayscale (in-place)
3
+ * @param {Uint8ClampedArray} pixels
4
+ */
5
+ export function vintage(pixels){
6
+
7
+ for(let i=0; i<pixels.length; i++){
8
+ let r = pixels[i]
9
+ let g = pixels[i+1]
10
+ let b = pixels[i+2]
11
+
12
+ pixels[i] = (0.393 * r) + (0.769 * g) + (0.189 * b);
13
+ pixels[i + 1] = (0.349 * r) + (0.686 * g) + (0.168 * b);
14
+ pixels[i + 2] = (0.272 * r) + (0.534 * g) + (0.131 * b);
15
+
16
+ }
17
+
18
+ }
@@ -0,0 +1,21 @@
1
+ export function ImageDataGenerate (file, canvas, ctx){
2
+ return new Promise((resolve)=>{
3
+ const image_icon = new Image()
4
+
5
+ image_icon.onload = ()=>{
6
+ SIZE = image_icon.width
7
+ canvas.width = image_icon.width;
8
+ canvas.height = image_icon.height;
9
+ ctx.fillStyle = "white"
10
+ ctx.clearRect(0, 0, SIZE, SIZE)
11
+ ctx.drawImage(image_icon, 0, 0, SIZE, SIZE)
12
+ resolve({
13
+ width:image_icon.width,
14
+ height:image_icon.height
15
+ })
16
+
17
+ }
18
+ image_icon.src = URL.createObjectURL(file)
19
+ })
20
+
21
+ }
package/index.js ADDED
@@ -0,0 +1,8 @@
1
+ export {BW} from "./filter/blackandwhite"
2
+ export {bLur} from "./filter/blur"
3
+ export {ASCII_generator} from "./filter/generate_ASCII"
4
+ export {inversion} from "./filter/inversion"
5
+ export {vintage} from "./filter/vintage"
6
+ export {encodeImageData} from "./encoder"
7
+ export {decodeImageData} from "./decoder"
8
+ export {ImageDataGenerate} from "./genImageData"
package/package.json ADDED
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "image-filter-toolkit",
3
+ "version": "1.0.0",
4
+ "description": "Image encode/decode, filters, ASCII generator using raw ImageData",
5
+ "keywords": [
6
+ "image",
7
+ "binary",
8
+ "ascii",
9
+ "canvas"
10
+ ],
11
+ "license": "MIT",
12
+ "author": "Neeraj Dhyani",
13
+ "type": "module",
14
+ "exports": {
15
+ ".": "./index.js"
16
+ },
17
+ "main": "index.js",
18
+ "scripts": {
19
+ "test": "echo \\\"No tests specified\\\"\""
20
+ }
21
+ }