Skip to content

Commit ba5f661

Browse files
authored
Merge pull request #878 from arduino/camera-filters
Add image filter dropdown to Web Serial Camera
2 parents 7ed8f10 + 80ebbf7 commit ba5f661

File tree

4 files changed

+67
-9
lines changed

4 files changed

+67
-9
lines changed

libraries/Camera/extras/WebSerialCamera/app.js

+38-7
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,14 @@ const connectButton = document.getElementById('connect');
2121
const refreshButton = document.getElementById('refresh');
2222
const startButton = document.getElementById('start');
2323
const saveImageButton = document.getElementById('save-image');
24+
const filterSelector = document.getElementById('filter-selector');
2425
const canvas = document.getElementById('bitmapCanvas');
2526
const ctx = canvas.getContext('2d');
2627

2728
const imageDataTransfomer = new ImageDataTransformer(ctx);
2829
imageDataTransfomer.setStartSequence([0xfa, 0xce, 0xfe, 0xed]);
2930
imageDataTransfomer.setStopSequence([0xda, 0xbb, 0xad, 0x00]);
3031

31-
// 🐣 Uncomment one of the following lines to apply a filter to the image data
32-
// imageDataTransfomer.filter = new GrayScaleFilter();
33-
// imageDataTransfomer.filter = new BlackAndWhiteFilter();
34-
// imageDataTransfomer.filter = new SepiaColorFilter();
35-
// imageDataTransfomer.filter = new PixelateFilter(8);
36-
// imageDataTransfomer.filter = new BlurFilter(8);
3732
const connectionHandler = new SerialConnectionHandler();
3833

3934

@@ -54,12 +49,20 @@ connectionHandler.onConnect = async () => {
5449
}
5550
imageDataTransfomer.setImageMode(imageMode);
5651
imageDataTransfomer.setResolution(imageResolution.width, imageResolution.height);
52+
53+
// Filters are only available for color images
54+
if(imageMode !== 'GRAYSCALE'){
55+
filterSelector.disabled = false;
56+
}
57+
5758
renderStream();
5859
};
5960

6061
connectionHandler.onDisconnect = () => {
61-
connectButton.textContent = 'Connect';
6262
imageDataTransfomer.reset();
63+
connectButton.textContent = 'Connect';
64+
filterSelector.disabled = true;
65+
filterSelector.value = 'none';
6366
};
6467

6568

@@ -122,9 +125,37 @@ saveImageButton.addEventListener('click', () => {
122125
link.remove();
123126
});
124127

128+
filterSelector.addEventListener('change', () => {
129+
const filter = filterSelector.value;
130+
switch(filter){
131+
case 'none':
132+
imageDataTransfomer.filter = null;
133+
break;
134+
case 'gray-scale':
135+
imageDataTransfomer.filter = new GrayScaleFilter();
136+
break;
137+
case 'black-and-white':
138+
imageDataTransfomer.filter = new BlackAndWhiteFilter();
139+
break;
140+
case 'sepia':
141+
imageDataTransfomer.filter = new SepiaColorFilter();
142+
break;
143+
case 'pixelate':
144+
imageDataTransfomer.filter = new PixelateFilter(8);
145+
break;
146+
case 'blur':
147+
imageDataTransfomer.filter = new BlurFilter(8);
148+
break;
149+
default:
150+
imageDataTransfomer.filter = null;
151+
}
152+
});
153+
125154
// On page load event, try to connect to the serial port
126155
window.addEventListener('load', async () => {
156+
filterSelector.disabled = true;
127157
console.log('🚀 Page loaded. Trying to connect to serial port...');
158+
128159
setTimeout(() => {
129160
connectionHandler.autoConnect();
130161
}, 1000);

libraries/Camera/extras/WebSerialCamera/index.html

+12-1
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,23 @@
99
<body>
1010
<div id="main-container">
1111
<canvas id="bitmapCanvas"></canvas>
12-
<div id="controls">
12+
<div class="controls">
1313
<button id="connect">Connect</button>
1414
<button id="save-image">Save Image</button>
1515
<button id="refresh">Refresh</button>
1616
<button id="start">Start</button>
1717
</div>
18+
<div class="controls">
19+
<label for="filter">Filter</label>
20+
<select id="filter-selector">
21+
<option value="none">None</option>
22+
<option value="gray-scale">Grayscale</option>
23+
<option value="black-and-white">Black and White</option>
24+
<option value="sepia">Sepia</option>
25+
<option value="pixelate">Pixelate</option>
26+
<option value="blur">Blur</option>
27+
</select>
28+
</div>
1829
</div>
1930
<script src="filters.js"></script>
2031
<script src="transformers.js"></script>

libraries/Camera/extras/WebSerialCamera/style.css

+16-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ body {
2222
margin-top: 20px;
2323
}
2424

25-
#controls {
25+
.controls {
2626
display: flex;
2727
flex-direction: row;
2828
align-items: center;
@@ -58,6 +58,21 @@ button:hover {
5858
background-color: var(--main-control-color-hover);
5959
}
6060

61+
label {
62+
font-family: 'Open Sans', sans-serif;
63+
font-size: 1rem;
64+
font-weight: bold;
65+
color: var(--secondary-text-color);
66+
}
67+
68+
select {
69+
font-family: 'Open Sans', sans-serif;
70+
font-size: 1rem;
71+
border: 1px solid #ccc;
72+
padding: 5px 10px;
73+
border-radius: 5px;
74+
}
75+
6176
#refresh {
6277
display: none;
6378
}

libraries/Camera/extras/WebSerialCamera/transformers.js

+1
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,7 @@ class ImageDataTransformer extends StartStopSequenceTransformer {
306306
this.imageMode = null;
307307
this.width = null;
308308
this.height = null;
309+
this.filter = null;
309310
this.imageDataProcessor.reset();
310311
}
311312

0 commit comments

Comments
 (0)