Skip to content

Commit ef056e4

Browse files
committed
Add funtionalities
1 parent fcc9f14 commit ef056e4

File tree

1 file changed

+241
-0
lines changed

1 file changed

+241
-0
lines changed

Source-Code/ImageFilter/script.js

Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,241 @@
1+
const canvas = document.getElementById('canvas');
2+
const ctx = canvas.getContext('2d');
3+
const img = new Image();
4+
const fileName = 'edited-image';
5+
let brightness = 0;
6+
let contrast = 0;
7+
let saturation = 0;
8+
let vibrance = 0;
9+
10+
// Handle file upload
11+
document.getElementById('upload-file').addEventListener('change', (e) => {
12+
const file = e.target.files[0];
13+
const reader = new FileReader();
14+
15+
reader.onload = function (event) {
16+
img.src = event.target.result;
17+
};
18+
19+
if (file) {
20+
reader.readAsDataURL(file);
21+
}
22+
});
23+
24+
// Helper function to clamp values
25+
function clamp(value) {
26+
return Math.min(Math.max(value, 0), 255);
27+
}
28+
29+
// Draw image to canvas
30+
img.onload = function () {
31+
canvas.width = img.width;
32+
canvas.height = img.height;
33+
ctx.drawImage(img, 0, 0);
34+
};
35+
36+
// Redraw image with current adjustments
37+
function drawImage() {
38+
ctx.drawImage(img, 0, 0);
39+
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
40+
const { data } = imageData;
41+
42+
// Apply brightness
43+
for (let i = 0; i < data.length; i += 4) {
44+
data[i] = clamp(data[i] + brightness); // Red
45+
data[i + 1] = clamp(data[i + 1] + brightness); // Green
46+
data[i + 2] = clamp(data[i + 2] + brightness); // Blue
47+
}
48+
49+
// Apply contrast
50+
const factor = (259 * (contrast + 255)) / (255 * (259 - contrast));
51+
for (let i = 0; i < data.length; i += 4) {
52+
data[i] = clamp(factor * (data[i] - 128) + 128); // Red
53+
data[i + 1] = clamp(factor * (data[i + 1] - 128) + 128); // Green
54+
data[i + 2] = clamp(factor * (data[i + 2] - 128) + 128); // Blue
55+
}
56+
57+
// Apply saturation
58+
for (let i = 0; i < data.length; i += 4) {
59+
const avg = (data[i] + data[i + 1] + data[i + 2]) / 3;
60+
data[i] = clamp(avg + (data[i] - avg) * (1 + saturation / 100)); // Red
61+
data[i + 1] = clamp(avg + (data[i + 1] - avg) * (1 + saturation / 100)); // Green
62+
data[i + 2] = clamp(avg + (data[i + 2] - avg) * (1 + saturation / 100)); // Blue
63+
}
64+
65+
// Apply vibrance
66+
for (let i = 0; i < data.length; i += 4) {
67+
const avg = (data[i] + data[i + 1] + data[i + 2]) / 3;
68+
const max = Math.max(data[i], data[i + 1], data[i + 2]);
69+
const amount = (((max - avg) * 2) / 255) * vibrance;
70+
data[i] = clamp(data[i] + amount); // Red
71+
data[i + 1] = clamp(data[i + 1] + amount); // Green
72+
data[i + 2] = clamp(data[i + 2] + amount); // Blue
73+
}
74+
ctx.putImageData(imageData, 0, 0);
75+
}
76+
77+
// Apply brightness
78+
function applyBrightness(value) {
79+
brightness += value;
80+
drawImage();
81+
}
82+
83+
// Apply contrast
84+
function applyContrast(value) {
85+
contrast += value;
86+
drawImage();
87+
}
88+
89+
// Apply saturation
90+
function applySaturation(value) {
91+
saturation += value;
92+
drawImage();
93+
}
94+
95+
// Apply vibrance
96+
function applyVibrance(value) {
97+
vibrance += value;
98+
drawImage();
99+
}
100+
101+
// Apply effect
102+
function applyEffect(effect) {
103+
drawImage();
104+
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
105+
const { data } = imageData;
106+
107+
if (effect === 'vintage') {
108+
// Vintage effect
109+
for (let i = 0; i < data.length; i += 4) {
110+
data[i] = clamp(data[i] * 0.9); // Red
111+
data[i + 1] = clamp(data[i + 1] * 0.7); // Green
112+
data[i + 2] = clamp(data[i + 2] * 0.5); // Blue
113+
}
114+
} else if (effect === 'lomo') {
115+
// Lomo effect
116+
for (let i = 0; i < data.length; i += 4) {
117+
data[i] = clamp(data[i] * 1.2); // Red
118+
data[i + 1] = clamp(data[i + 1] * 1.2); // Green
119+
data[i + 2] = clamp(data[i + 2] * 1.2); // Blue
120+
}
121+
} else if (effect === 'clarity') {
122+
// Clarity effect
123+
// (Increase contrast)
124+
applyContrast(20);
125+
} else if (effect === 'sincity') {
126+
// Sin City effect
127+
for (let i = 0; i < data.length; i += 4) {
128+
const avg = (data[i] + data[i + 1] + data[i + 2]) / 3;
129+
data[i] = avg; // Red
130+
data[i + 1] = avg; // Green
131+
data[i + 2] = avg; // Blue
132+
}
133+
} else if (effect === 'crossprocess') {
134+
// Cross Process effect
135+
for (let i = 0; i < data.length; i += 4) {
136+
data[i] = clamp(data[i] * 1.3); // Red
137+
data[i + 1] = clamp(data[i + 1] * 1.1); // Green
138+
data[i + 2] = clamp(data[i + 2] * 0.9); // Blue
139+
}
140+
} else if (effect === 'pinhole') {
141+
// Pinhole effect
142+
for (let i = 0; i < data.length; i += 4) {
143+
const avg = (data[i] + data[i + 1] + data[i + 2]) / 3;
144+
data[i] = avg * 0.9; // Red
145+
data[i + 1] = avg * 0.9; // Green
146+
data[i + 2] = avg * 0.9; // Blue
147+
}
148+
} else if (effect === 'nostalgia') {
149+
// Nostalgia effect
150+
for (let i = 0; i < data.length; i += 4) {
151+
data[i] = clamp(data[i] * 0.9 + 50); // Red
152+
data[i + 1] = clamp(data[i + 1] * 0.7 + 20); // Green
153+
data[i + 2] = clamp(data[i + 2] * 0.5 + 10); // Blue
154+
}
155+
} else if (effect === 'hermajesty') {
156+
// Her Majesty effect
157+
for (let i = 0; i < data.length; i += 4) {
158+
data[i] = clamp(data[i] * 1.1); // Red
159+
data[i + 1] = clamp(data[i + 1] * 0.95); // Green
160+
data[i + 2] = clamp(data[i + 2] * 1.3); // Blue
161+
}
162+
}
163+
164+
ctx.putImageData(imageData, 0, 0);
165+
}
166+
167+
// Download image
168+
function downloadImage() {
169+
const link = document.createElement('a');
170+
link.download = fileName;
171+
link.href = canvas.toDataURL('image/jpeg');
172+
link.click();
173+
}
174+
175+
// Revert filters
176+
function revertFilters() {
177+
brightness = 0;
178+
contrast = 0;
179+
saturation = 0;
180+
vibrance = 0;
181+
drawImage();
182+
}
183+
184+
// Event listeners for filter buttons
185+
document
186+
.querySelector('.brightness-add')
187+
.addEventListener('click', () => applyBrightness(10));
188+
document
189+
.querySelector('.brightness-remove')
190+
.addEventListener('click', () => applyBrightness(-10));
191+
document
192+
.querySelector('.contrast-add')
193+
.addEventListener('click', () => applyContrast(10));
194+
document
195+
.querySelector('.contrast-remove')
196+
.addEventListener('click', () => applyContrast(-10));
197+
document
198+
.querySelector('.saturation-add')
199+
.addEventListener('click', () => applySaturation(10));
200+
document
201+
.querySelector('.saturation-remove')
202+
.addEventListener('click', () => applySaturation(-10));
203+
document
204+
.querySelector('.vibrance-add')
205+
.addEventListener('click', () => applyVibrance(10));
206+
document
207+
.querySelector('.vibrance-remove')
208+
.addEventListener('click', () => applyVibrance(-10));
209+
210+
// Event listeners for effect buttons
211+
document
212+
.querySelector('.vintage-add')
213+
.addEventListener('click', () => applyEffect('vintage'));
214+
document
215+
.querySelector('.lomo-add')
216+
.addEventListener('click', () => applyEffect('lomo'));
217+
document
218+
.querySelector('.clarity-add')
219+
.addEventListener('click', () => applyEffect('clarity'));
220+
document
221+
.querySelector('.sincity-add')
222+
.addEventListener('click', () => applyEffect('sincity'));
223+
224+
document
225+
.querySelector('.crossprocess-add')
226+
.addEventListener('click', () => applyEffect('crossprocess'));
227+
document
228+
.querySelector('.pinhole-add')
229+
.addEventListener('click', () => applyEffect('pinhole'));
230+
document
231+
.querySelector('.nostalgia-add')
232+
.addEventListener('click', () => applyEffect('nostalgia'));
233+
document
234+
.querySelector('.hermajesty-add')
235+
.addEventListener('click', () => applyEffect('hermajesty'));
236+
237+
// Event listeners for download and revert buttons
238+
document
239+
.getElementById('download-btn')
240+
.addEventListener('click', downloadImage);
241+
document.getElementById('revert-btn').addEventListener('click', revertFilters);

0 commit comments

Comments
 (0)