frontbacked-svg 5.0.0 → 5.0.2

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/src/filters.ts CHANGED
@@ -1,226 +1,226 @@
1
- import { FilterArgs, Filters } from "./types.ts";
2
- import { AnalyzeResult, transformImageByTemplate } from "./imagePassportUtils.ts";
3
- import { ImageWrapper } from './polyfills/Image.ts';
4
- import { getCanvas } from "./imageHelper.ts";
5
-
6
- const isNode = typeof window === 'undefined';
7
- // Helper function to apply the filter
8
- const applyFilter = (base64ImageString: string, filter: (data: ImageData, args?: FilterArgs | null) => void, args?: FilterArgs | null): Promise<string> => {
9
- //alert(`Filter will apply`)
10
- return new Promise((resolve, reject) => {
11
- const img = new Image();
12
-
13
- img.onload = () => {
14
-
15
- const canvas = getCanvas(img.width, img.width);
16
- //const canvas = document.createElement('canvas');
17
- const ctx = canvas.getContext('2d') as any;
18
- if (!ctx) {
19
- return reject(new Error("Canvas not supported"));
20
- }
21
-
22
- canvas.width = img.width;
23
- canvas.height = img.height;
24
- const realImage = ((img as any) as ImageWrapper).realImage? ((img as any) as ImageWrapper).realImage : img
25
- ctx.drawImage(realImage, 0, 0);
26
-
27
- const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
28
- filter(imageData, args);
29
- ctx.putImageData(imageData, 0, 0);
30
-
31
- resolve(canvas.toDataURL());
32
- };
33
-
34
- img.src = base64ImageString;
35
-
36
- img.onerror = reject;
37
- });
38
- };
39
-
40
- const BLUR_RADII = ["0.1", "0.2", "0.3", "0.4", "0.5", "0.6", "0.7",/* "0.8", "0.9", "1"*/]
41
- // Define the FILTERS object with filter functions and corresponding React components
42
- const FILTERS: Filters = {
43
- Whitescale: {
44
- id: "Whitescale",
45
- filter: (base64ImageString) => applyFilter(base64ImageString, (data) => {
46
- const pixels = data.data;
47
- for (let i = 0; i < pixels.length; i += 4) {
48
- pixels[i] = 255; // R
49
- pixels[i + 1] = 255; // G
50
- pixels[i + 2] = 255; // B
51
- }
52
- })
53
- },
54
- Blackscale: {
55
- id: "Blackscale",
56
- filter: (base64ImageString) => applyFilter(base64ImageString, (data) => {
57
- const pixels = data.data;
58
- for (let i = 0; i < pixels.length; i += 4) {
59
- pixels[i] = 0; // R
60
- pixels[i + 1] = 0; // G
61
- pixels[i + 2] = 0; // B
62
- }
63
- })
64
- },
65
- Greyscale: {
66
- id: "Greyscale",
67
- filter: (base64ImageString) => applyFilter(base64ImageString, (data) => {
68
- const pixels = data.data;
69
- for (let i = 0; i < pixels.length; i += 4) {
70
- const avg = (pixels[i] + pixels[i + 1] + pixels[i + 2]) / 3;
71
- pixels[i] = avg; // R
72
- pixels[i + 1] = avg; // G
73
- pixels[i + 2] = avg; // B
74
- }
75
- })
76
- },
77
- Redscale: {
78
- id: "Redscale",
79
- filter: (base64ImageString) => applyFilter(base64ImageString, (data) => {
80
- const pixels = data.data;
81
- for (let i = 0; i < pixels.length; i += 4) {
82
- pixels[i + 1] = 0; // G
83
- pixels[i + 2] = 0; // B
84
- }
85
- })
86
- },
87
- Greenscale: {
88
- id: "Greenscale",
89
- filter: (base64ImageString) => applyFilter(base64ImageString, (data) => {
90
- const pixels = data.data;
91
- for (let i = 0; i < pixels.length; i += 4) {
92
- pixels[i] = 0; // R
93
- pixels[i + 2] = 0; // B
94
- }
95
- })
96
- },
97
- Bluescale: {
98
- id: "Bluescale",
99
- filter: (base64ImageString) => applyFilter(base64ImageString, (data) => {
100
- const pixels = data.data;
101
- for (let i = 0; i < pixels.length; i += 4) {
102
- pixels[i] = 0; // R
103
- pixels[i + 1] = 0; // G
104
- }
105
- })
106
- },
107
- Sepia: {
108
- id: "Sepia",
109
- filter: (base64ImageString, args) => applyFilter(base64ImageString, (data) => {
110
- // Set default values for sepia transformation or use provided args
111
- const rMult = args?.rMult ?? 0.393;
112
- const gMult = args?.gMult ?? 0.769;
113
- const bMult = args?.bMult ?? 0.189;
114
- const rAdd = args?.rAdd ?? 0.349;
115
- const gAdd = args?.gAdd ?? 0.686;
116
- const bAdd = args?.bAdd ?? 0.272;
117
-
118
- const pixels = data.data;
119
- for (let i = 0; i < pixels.length; i += 4) {
120
- const r = pixels[i]; // Red
121
- const g = pixels[i + 1]; // Green
122
- const b = pixels[i + 2]; // Blue
123
-
124
- // Apply customizable sepia transformation
125
- const tr = rMult * r + gMult * g + bMult * b;
126
- const tg = rAdd * r + gAdd * g + bAdd * b;
127
- const tb = bAdd * r + bAdd * g + bAdd * b;
128
-
129
- pixels[i] = tr > 255 ? 255 : tr; // Red
130
- pixels[i + 1] = tg > 255 ? 255 : tg; // Green
131
- pixels[i + 2] = tb > 255 ? 255 : tb; // Blue
132
- }
133
- })
134
- },
135
- Guassianblur: {
136
- id: "Guassianblur",
137
- filter: (base64ImageString, args) => applyFilter(base64ImageString, (data, args) => {
138
- const minRadius = Number(BLUR_RADII[0])
139
- const maxRadius = Number(BLUR_RADII[BLUR_RADII.length - 1])
140
- var radius = args?.radius && !isNaN(args.radius) ? Number(args.radius) : minRadius;// Default radius
141
- if(radius > maxRadius) radius = minRadius;
142
- radius *= 10;
143
-
144
- const pixels = data.data;
145
- const width = data.width;
146
- const height = data.height;
147
-
148
- // Create a copy of the original pixel data
149
- const copyData = new Uint8ClampedArray(pixels);
150
-
151
- // Apply separable Gaussian blur: first horizontal, then vertical
152
- // Horizontal pass
153
- function blurHorizontal() {
154
- for (let y = 0; y < height; y++) {
155
- for (let x = 0; x < width; x++) {
156
- let r = 0, g = 0, b = 0, a = 0, count = 0;
157
-
158
- for (let dx = -radius; dx <= radius; dx++) {
159
- const nx = x + dx;
160
-
161
- if (nx >= 0 && nx < width) {
162
- const i = (y * width + nx) * 4;
163
- r += copyData[i];
164
- g += copyData[i + 1];
165
- b += copyData[i + 2];
166
- a += copyData[i + 3];
167
- count++;
168
- }
169
- }
170
-
171
- const idx = (y * width + x) * 4;
172
- pixels[idx] = r / count;
173
- pixels[idx + 1] = g / count;
174
- pixels[idx + 2] = b / count;
175
- pixels[idx + 3] = a / count;
176
- }
177
- }
178
- }
179
-
180
- // Vertical pass
181
- function blurVertical() {
182
- for (let x = 0; x < width; x++) {
183
- for (let y = 0; y < height; y++) {
184
- let r = 0, g = 0, b = 0, a = 0, count = 0;
185
-
186
- for (let dy = -radius; dy <= radius; dy++) {
187
- const ny = y + dy;
188
-
189
- if (ny >= 0 && ny < height) {
190
- const i = (ny * width + x) * 4;
191
- r += copyData[i];
192
- g += copyData[i + 1];
193
- b += copyData[i + 2];
194
- a += copyData[i + 3];
195
- count++;
196
- }
197
- }
198
-
199
- const idx = (y * width + x) * 4;
200
- pixels[idx] = r / count;
201
- pixels[idx + 1] = g / count;
202
- pixels[idx + 2] = b / count;
203
- pixels[idx + 3] = a / count;
204
- }
205
- }
206
- }
207
-
208
- // Apply the separable blur
209
- blurHorizontal(); // First pass
210
- blurVertical(); // Second pass
211
- }, args)
212
- },/*
213
- Rotate: {
214
- id: "Rotate",
215
- filter: (base64ImageString, args) => new Promise((resolve, reject) => {
216
- resolve(base64ImageString)
217
- }),
218
- render: null
219
- },*/
220
- ImageTransform: {
221
- id: "ImageTransform",
222
- filter: (base64ImageString, args) => transformImageByTemplate(args as AnalyzeResult, base64ImageString, 2)
223
- },
224
- }
225
-
1
+ import { FilterArgs, Filters } from "./types.ts";
2
+ import { AnalyzeResult, transformImageByTemplate } from "./imagePassportUtils.ts";
3
+ import { ImageWrapper } from './polyfills/Image.ts';
4
+ import { getCanvas } from "./imageHelper.ts";
5
+
6
+ const isNode = typeof window === 'undefined';
7
+ // Helper function to apply the filter
8
+ const applyFilter = (base64ImageString: string, filter: (data: ImageData, args?: FilterArgs | null) => void, args?: FilterArgs | null): Promise<string> => {
9
+ //alert(`Filter will apply`)
10
+ return new Promise((resolve, reject) => {
11
+ const img = new Image();
12
+
13
+ img.onload = () => {
14
+
15
+ const canvas = getCanvas(img.width, img.width);
16
+ //const canvas = document.createElement('canvas');
17
+ const ctx = canvas.getContext('2d') as any;
18
+ if (!ctx) {
19
+ return reject(new Error("Canvas not supported"));
20
+ }
21
+
22
+ canvas.width = img.width;
23
+ canvas.height = img.height;
24
+ const realImage = ((img as any) as ImageWrapper).realImage? ((img as any) as ImageWrapper).realImage : img
25
+ ctx.drawImage(realImage, 0, 0);
26
+
27
+ const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
28
+ filter(imageData, args);
29
+ ctx.putImageData(imageData, 0, 0);
30
+
31
+ resolve(canvas.toDataURL());
32
+ };
33
+
34
+ img.src = base64ImageString;
35
+
36
+ img.onerror = reject;
37
+ });
38
+ };
39
+
40
+ const BLUR_RADII = ["0.1", "0.2", "0.3", "0.4", "0.5", "0.6", "0.7",/* "0.8", "0.9", "1"*/]
41
+ // Define the FILTERS object with filter functions and corresponding React components
42
+ const FILTERS: Filters = {
43
+ Whitescale: {
44
+ id: "Whitescale",
45
+ filter: (base64ImageString) => applyFilter(base64ImageString, (data) => {
46
+ const pixels = data.data;
47
+ for (let i = 0; i < pixels.length; i += 4) {
48
+ pixels[i] = 255; // R
49
+ pixels[i + 1] = 255; // G
50
+ pixels[i + 2] = 255; // B
51
+ }
52
+ })
53
+ },
54
+ Blackscale: {
55
+ id: "Blackscale",
56
+ filter: (base64ImageString) => applyFilter(base64ImageString, (data) => {
57
+ const pixels = data.data;
58
+ for (let i = 0; i < pixels.length; i += 4) {
59
+ pixels[i] = 0; // R
60
+ pixels[i + 1] = 0; // G
61
+ pixels[i + 2] = 0; // B
62
+ }
63
+ })
64
+ },
65
+ Greyscale: {
66
+ id: "Greyscale",
67
+ filter: (base64ImageString) => applyFilter(base64ImageString, (data) => {
68
+ const pixels = data.data;
69
+ for (let i = 0; i < pixels.length; i += 4) {
70
+ const avg = (pixels[i] + pixels[i + 1] + pixels[i + 2]) / 3;
71
+ pixels[i] = avg; // R
72
+ pixels[i + 1] = avg; // G
73
+ pixels[i + 2] = avg; // B
74
+ }
75
+ })
76
+ },
77
+ Redscale: {
78
+ id: "Redscale",
79
+ filter: (base64ImageString) => applyFilter(base64ImageString, (data) => {
80
+ const pixels = data.data;
81
+ for (let i = 0; i < pixels.length; i += 4) {
82
+ pixels[i + 1] = 0; // G
83
+ pixels[i + 2] = 0; // B
84
+ }
85
+ })
86
+ },
87
+ Greenscale: {
88
+ id: "Greenscale",
89
+ filter: (base64ImageString) => applyFilter(base64ImageString, (data) => {
90
+ const pixels = data.data;
91
+ for (let i = 0; i < pixels.length; i += 4) {
92
+ pixels[i] = 0; // R
93
+ pixels[i + 2] = 0; // B
94
+ }
95
+ })
96
+ },
97
+ Bluescale: {
98
+ id: "Bluescale",
99
+ filter: (base64ImageString) => applyFilter(base64ImageString, (data) => {
100
+ const pixels = data.data;
101
+ for (let i = 0; i < pixels.length; i += 4) {
102
+ pixels[i] = 0; // R
103
+ pixels[i + 1] = 0; // G
104
+ }
105
+ })
106
+ },
107
+ Sepia: {
108
+ id: "Sepia",
109
+ filter: (base64ImageString, args) => applyFilter(base64ImageString, (data) => {
110
+ // Set default values for sepia transformation or use provided args
111
+ const rMult = args?.rMult ?? 0.393;
112
+ const gMult = args?.gMult ?? 0.769;
113
+ const bMult = args?.bMult ?? 0.189;
114
+ const rAdd = args?.rAdd ?? 0.349;
115
+ const gAdd = args?.gAdd ?? 0.686;
116
+ const bAdd = args?.bAdd ?? 0.272;
117
+
118
+ const pixels = data.data;
119
+ for (let i = 0; i < pixels.length; i += 4) {
120
+ const r = pixels[i]; // Red
121
+ const g = pixels[i + 1]; // Green
122
+ const b = pixels[i + 2]; // Blue
123
+
124
+ // Apply customizable sepia transformation
125
+ const tr = rMult * r + gMult * g + bMult * b;
126
+ const tg = rAdd * r + gAdd * g + bAdd * b;
127
+ const tb = bAdd * r + bAdd * g + bAdd * b;
128
+
129
+ pixels[i] = tr > 255 ? 255 : tr; // Red
130
+ pixels[i + 1] = tg > 255 ? 255 : tg; // Green
131
+ pixels[i + 2] = tb > 255 ? 255 : tb; // Blue
132
+ }
133
+ })
134
+ },
135
+ Guassianblur: {
136
+ id: "Guassianblur",
137
+ filter: (base64ImageString, args) => applyFilter(base64ImageString, (data, args) => {
138
+ const minRadius = Number(BLUR_RADII[0])
139
+ const maxRadius = Number(BLUR_RADII[BLUR_RADII.length - 1])
140
+ var radius = args?.radius && !isNaN(args.radius) ? Number(args.radius) : minRadius;// Default radius
141
+ if(radius > maxRadius) radius = minRadius;
142
+ radius *= 10;
143
+
144
+ const pixels = data.data;
145
+ const width = data.width;
146
+ const height = data.height;
147
+
148
+ // Create a copy of the original pixel data
149
+ const copyData = new Uint8ClampedArray(pixels);
150
+
151
+ // Apply separable Gaussian blur: first horizontal, then vertical
152
+ // Horizontal pass
153
+ function blurHorizontal() {
154
+ for (let y = 0; y < height; y++) {
155
+ for (let x = 0; x < width; x++) {
156
+ let r = 0, g = 0, b = 0, a = 0, count = 0;
157
+
158
+ for (let dx = -radius; dx <= radius; dx++) {
159
+ const nx = x + dx;
160
+
161
+ if (nx >= 0 && nx < width) {
162
+ const i = (y * width + nx) * 4;
163
+ r += copyData[i];
164
+ g += copyData[i + 1];
165
+ b += copyData[i + 2];
166
+ a += copyData[i + 3];
167
+ count++;
168
+ }
169
+ }
170
+
171
+ const idx = (y * width + x) * 4;
172
+ pixels[idx] = r / count;
173
+ pixels[idx + 1] = g / count;
174
+ pixels[idx + 2] = b / count;
175
+ pixels[idx + 3] = a / count;
176
+ }
177
+ }
178
+ }
179
+
180
+ // Vertical pass
181
+ function blurVertical() {
182
+ for (let x = 0; x < width; x++) {
183
+ for (let y = 0; y < height; y++) {
184
+ let r = 0, g = 0, b = 0, a = 0, count = 0;
185
+
186
+ for (let dy = -radius; dy <= radius; dy++) {
187
+ const ny = y + dy;
188
+
189
+ if (ny >= 0 && ny < height) {
190
+ const i = (ny * width + x) * 4;
191
+ r += copyData[i];
192
+ g += copyData[i + 1];
193
+ b += copyData[i + 2];
194
+ a += copyData[i + 3];
195
+ count++;
196
+ }
197
+ }
198
+
199
+ const idx = (y * width + x) * 4;
200
+ pixels[idx] = r / count;
201
+ pixels[idx + 1] = g / count;
202
+ pixels[idx + 2] = b / count;
203
+ pixels[idx + 3] = a / count;
204
+ }
205
+ }
206
+ }
207
+
208
+ // Apply the separable blur
209
+ blurHorizontal(); // First pass
210
+ blurVertical(); // Second pass
211
+ }, args)
212
+ },/*
213
+ Rotate: {
214
+ id: "Rotate",
215
+ filter: (base64ImageString, args) => new Promise((resolve, reject) => {
216
+ resolve(base64ImageString)
217
+ }),
218
+ render: null
219
+ },*/
220
+ ImageTransform: {
221
+ id: "ImageTransform",
222
+ filter: (base64ImageString, args) => transformImageByTemplate(args as AnalyzeResult, base64ImageString, 2)
223
+ },
224
+ }
225
+
226
226
  export default FILTERS