Skip to content

Commit b073364

Browse files
committed
Proj 19: Figured out that I need to square the resolution in array len calc. Also that canvas positioning and CSS scaling adds many data to the image data array. The resulting effect is two tiny, squished images...which would be nice for stereoscopy if they were actually from two different angles..
1 parent 238ae60 commit b073364

4 files changed

Lines changed: 88 additions & 88 deletions

File tree

19--Webcam_Fun/css/theme.css

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
.ctrls legend .value,
1919
.ctrls label .value {
2020
border-radius:1rem;
21-
color:rgb(51,51,51);
21+
/* color:rgb(51,51,51); */
22+
color:rgb(255,255,255);
2223
background-color:rgb(204,204,204);
2324
/* box-shadow:0 0.125rem 0.5rem 0 rgba(0, 0, 0, 0.5); */
2425
}

19--Webcam_Fun/index-jds.html

Lines changed: 5 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,25 +11,20 @@
1111
<link rel="stylesheet" href="css/theme.css">
1212
</head>
1313
<body>
14-
1514
<header>
1615
<h1>webcam fun</h1>
1716
</header>
18-
1917
<main>
20-
2118
<div class="ctrls">
2219
<fieldset id="ctrl_camera">
2320
<legend>cam</legend>
2421
<button class="btn_on status success">On</button>
2522
<button class="btn_off status error">Off</button>
26-
2723
<!-- convert on/off buttons into checkbox toggle -->
2824
<!-- <label class="" for="cam">
2925
<input type="checkbox" id="cam" class="input-toggle">
3026
<span class="label">On?</span>
3127
</label> -->
32-
3328
<button class="btn_clear disabled" disabled>Clear</button>
3429
</fieldset>
3530
<fieldset id="ctrl_fx">
@@ -39,9 +34,9 @@ <h1>webcam fun</h1>
3934
<option value="Colorize">Colorize</option>
4035
<option value="ChannelSplit">ChannelSplit</option>
4136
<option value="ChromaKey">ChromaKey</option>
37+
<option value="Invert">Invert</option>
4238
<option value="Saturate">Saturate</option>
4339
<option value="Pixelate">Pixelate</option>
44-
<option value="Invert">Invert</option>
4540
</select>
4641
<!-- add checkbox toggle for mirror effect -->
4742
<label class="setting" for="mirror">
@@ -159,7 +154,7 @@ <h1>webcam fun</h1>
159154
</tr>
160155
<!-- <tr>
161156
<td colspan="4">
162-
<button class="btn_clear disabled" disabled>Clear</button>
157+
<button class="btn_reset disabled" disabled>Reset</button>
163158
</td>
164159
</tr> -->
165160
</tbody>
@@ -174,9 +169,6 @@ <h1>webcam fun</h1>
174169
</label>
175170
</td>
176171
</tr>
177-
<tr>
178-
<td><button class="btn_apply status success">Apply</button></td>
179-
</tr>
180172
</tbody>
181173
</table>
182174
<table class="ctrl_group" id="ctrl_fx_pixelate">
@@ -185,28 +177,22 @@ <h1>webcam fun</h1>
185177
<td>
186178
<label>
187179
<span>pixelate: <code class="value">0</code></span>
188-
<input id="pixelate" type="range" class="input-range" value=3 min=1 max=10>
180+
<input id="pixelate" type="range" class="input-range" value=2 min=1 max=10>
189181
</label>
190182
</td>
191183
</tr>
192-
<tr>
193-
<td><button class="btn_apply status success">Apply</button></td>
194-
</tr>
195184
</tbody>
196185
</table>
197186
<table class="ctrl_group" id="ctrl_fx_invert">
198187
<tbody>
199188
<tr>
200189
<td>
201190
<label>
202-
<input id="invert" type="checkbox" class="input-toggle">
203-
<span>invert</span>
191+
<!-- <input id="invert" type="checkbox" class="input-toggle"> -->
192+
<span>invert: <code class="value">ON</code></span>
204193
</label>
205194
</td>
206195
</tr>
207-
<!-- <tr>
208-
<td><button class="btn_apply status success">Apply</button></td>
209-
</tr> -->
210196
</tbody>
211197
</table>
212198
</fieldset>
@@ -221,23 +207,17 @@ <h1>webcam fun</h1>
221207
<button class="btn_clear disabled" disabled>Clear</button>
222208
</fieldset>
223209
</div>
224-
225210
<div class="photobooth">
226211
<video class="video"></video>
227212
<canvas class="canvas"></canvas>
228213
</div>
229-
230214
<div class="strip"></div>
231-
232215
</main>
233-
234216
<audio class="sound-snap" src="snap.mp3" hidden></audio>
235-
236217
<script src="js/utils.js"></script>
237218
<script src="js/scripts.js"></script>
238219
<script src="js/fx.js"></script>
239220
<!-- <script src="js/mirror.js"></script> -->
240221
<!-- <script src="scripts-FINISHED.js"></script> -->
241-
242222
</body>
243223
</html>

19--Webcam_Fun/js/fx.js

Lines changed: 76 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
/* fx.js */
22
console.log('fx.js READY!');
3+
4+
/**
5+
* Uint8ClampedArray
6+
*/
7+
38
/**
49
* check if each pixel's color value falls within ranges set
510
* by inputs. if it does, drop alpha value to 0 to hide pixel.
611
* @param {big array} data - The pixels.
712
* @return {big array} - The modified pixels.
813
*/
9-
function fFxChromaKey(uint8) {
14+
function fFxChromaKey(array255) {
1015
// console.log('START fFxChromaKey');
1116
// create empty array of min & max values
1217
const levels = {};
@@ -16,12 +21,12 @@ function fFxChromaKey(uint8) {
1621
});
1722
// console.log(levels);
1823
// debugger;
19-
for (let i = 0; i < uint8.data.length; i+=4) {
24+
for (let i = 0; i < array255.data.length; i+=4) {
2025
// put values into vars
21-
red = uint8.data[i+0]; // r
22-
green = uint8.data[i+1]; // g
23-
blue = uint8.data[i+2]; // b
24-
alpha = uint8.data[i+3]; // a
26+
red = array255.data[i+0]; // r
27+
green = array255.data[i+1]; // g
28+
blue = array255.data[i+2]; // b
29+
alpha = array255.data[i+3]; // a
2530

2631
// check if values are within ranges
2732
if (red >= levels.rmin
@@ -31,10 +36,10 @@ function fFxChromaKey(uint8) {
3136
&& blue >= levels.bmin
3237
&& blue <= levels.bmax) {
3338
// take it out!
34-
uint8.data[i + 3] = 0;
39+
array255.data[i + 3] = 0;
3540
}
3641
}
37-
return uint8;
42+
return array255;
3843
}
3944

4045
/**
@@ -45,14 +50,14 @@ function fFxChromaKey(uint8) {
4550
* @param {array} nums - Integers used to shift each R, G, and B value.
4651
* @return {big array} - The modified pixels.
4752
*/
48-
function fFxChannelSplit(uint8,nums) {
53+
function fFxChannelSplit(array255,nums) {
4954
// console.log('START fFxChannelSplit');
50-
for (let i = 0; i < uint8.data.length; i+=4) {
51-
uint8.data[i+nums[0]] = uint8.data[i+0]; // r
52-
uint8.data[i+nums[1]] = uint8.data[i+1]; // g
53-
uint8.data[i+nums[2]] = uint8.data[i+2]; // b
55+
for (let i = 0; i < array255.data.length; i+=4) {
56+
array255.data[i+nums[0]] = array255.data[i+0]; // r
57+
array255.data[i+nums[1]] = array255.data[i+1]; // g
58+
array255.data[i+nums[2]] = array255.data[i+2]; // b
5459
}
55-
return uint8;
60+
return array255;
5661
}
5762

5863
/**
@@ -62,14 +67,14 @@ function fFxChannelSplit(uint8,nums) {
6267
* @param {array} nums - Integers used to shift each R, G, and B value.
6368
* @return {big array} - The modified pixels.
6469
*/
65-
function fFxColorize(uint8,nums) {
70+
function fFxColorize(array255,nums) {
6671
// console.log('START fFxRGB',nums);
67-
for (let i = 0; i < uint8.data.length; i+=4) {
68-
uint8.data[i+0] += nums[0]; // r
69-
uint8.data[i+1] += nums[1]; // g
70-
uint8.data[i+2] += nums[2]; // b
72+
for (let i = 0; i < array255.data.length; i+=4) {
73+
array255.data[i+0] += nums[0]; // r
74+
array255.data[i+1] += nums[1]; // g
75+
array255.data[i+2] += nums[2]; // b
7176
}
72-
return uint8;
77+
return array255;
7378
}
7479

7580
/**
@@ -78,65 +83,79 @@ function fFxColorize(uint8,nums) {
7883
* @param {number} saturation - How saturated the video should be: 0 = monochrome, 100 = normal color, 200 = super color.
7984
* @return {big array} - The modified pixels.
8085
*/
81-
function fFxSaturate(uint8,nums) {
86+
function fFxSaturate(array255,nums) {
8287
// console.log('START fFxSaturate',nums);
83-
for (let i = 0; i < uint8.data.length; i+=4) {
88+
for (let i = 0; i < array255.data.length; i+=4) {
8489
/* add color values together to get average */
85-
const avg = (uint8.data[i+0] + uint8.data[i+1] + uint8.data[i+2])/3;
90+
const avg = (array255.data[i+0] + array255.data[i+1] + array255.data[i+2])/3;
8691
/* apply average to R,G, and B values of each pixel */
87-
uint8.data[i+0] = (avg*nums[0])+(uint8.data[i+0]*nums[1]); // r
88-
uint8.data[i+1] = (avg*nums[0])+(uint8.data[i+1]*nums[1]); // g
89-
uint8.data[i+2] = (avg*nums[0])+(uint8.data[i+2]*nums[1]); // b
92+
array255.data[i+0] = (avg*nums[0])+(array255.data[i+0]*nums[1]); // r
93+
array255.data[i+1] = (avg*nums[0])+(array255.data[i+1]*nums[1]); // g
94+
array255.data[i+2] = (avg*nums[0])+(array255.data[i+2]*nums[1]); // b
9095
}
91-
return uint8;
96+
return array255;
9297
}
9398

9499
/**
95-
* [invert description]
100+
* [fFxInvert description]
96101
* @return {[type]} [description]
97102
*/
98-
function fFxInvert (uint8) {
99-
for (var i = 0; i < uint8.data.length; i += 4) {
100-
uint8.data[i+0] = 255 - uint8.data[i+0]; // red
101-
uint8.data[i+1] = 255 - uint8.data[i+1]; // green
102-
uint8.data[i+2] = 255 - uint8.data[i+2]; // blue
103+
function fFxInvert (array255) {
104+
for (var i = 0; i < array255.data.length; i += 4) {
105+
array255.data[i+0] = 255 - array255.data[i+0]; // red
106+
array255.data[i+1] = 255 - array255.data[i+1]; // green
107+
array255.data[i+2] = 255 - array255.data[i+2]; // blue
103108
}
104-
return uint8;
109+
return array255;
105110
};
106111

107-
108112
/**
109113
* [fFxPixelate description]
110114
* @param {big array} data - The pixels.
111115
* @param {number} res - Resolution of the pixels: 1 = 1:1, 2 = 1:2, 3 = 1:3, etc.
112116
* @return {big array} - The modified pixels.
113117
*/
114-
function fFxPixelate(uint8,res) {
115-
// console.log('START fFxPixelate',res);
116-
/* Uint8ClampedArray */
117-
console.dir(uint8);
118-
console.dir(uint8.data);
119-
// console.log('uint8.data.length: ',uint8.data.length);
120-
// console.log('uint8.width: ',uint8.width);
121-
let compressed = [];
122-
for (let i = 0; i < uint8.data.length; i+=4) {
123-
if ( ((i/4) % res) === 0 ) {
118+
function fFxPixelate(array255,res) {
119+
// console.group('START fFxPixelate',res);
120+
// console.log('array255: ',array255);
121+
// console.dir(array255.data);
122+
123+
// console.log('array255.data.length: ',array255.data.length);
124+
// console.log('array255.height: ',array255.height);
125+
// console.log('array255.width: ',array255.width);
126+
127+
128+
const newLength = array255.data.length/res*res;
129+
// console.log('newLength: ', newLength);
130+
const newHeight = Math.floor(array255.height/res);
131+
// console.log('newHeight: ', newHeight);
132+
const newWidth = Math.floor(array255.width/res);
133+
// console.log('newWidth: ', newWidth);
134+
135+
let newData = [];
136+
for (let i = 0; i < array255.data.length; i+=4) {
137+
if ( (i % (4*res*res)) === 0 ) {
138+
// console.log('i: ',i);
124139
// console.log('slicing');
125-
compressed.push(uint8.data[i+0]);
126-
compressed.push(uint8.data[i+1]);
127-
compressed.push(uint8.data[i+2]);
128-
compressed.push(uint8.data[i+3]);
140+
newData.push(array255.data[i]);
141+
newData.push(array255.data[i+1]);
142+
newData.push(array255.data[i+2]);
143+
newData.push(array255.data[i+3]);
129144
} else {
130145
// console.log('NOT slicing');
131146
}
132147
}
133-
console.log('compressed.length: ',compressed.length);
134-
console.log('compressed.length/4: ',compressed.length/4);
135-
debugger;
136-
// console.dir(Uint8ClampedArray.from(compressed));
137-
// uint8.data = new Uint8ClampedArray(compressed);
138-
compressed = Uint8ClampedArray.from(compressed);
139-
// console.dir(compressed);
140-
let newImageData = new ImageData(compressed, (uint8.width/res), (uint8.height/res));
148+
// console.log('newData: ',newData);
149+
// console.log('newData.length: ',newData.length);
150+
/* need to disable canves scaling and centering in order to properly calculate the canvas dimaensions and length of the ImageData array */
151+
// console.log('newData.length/(4): ',newData.length/(4));
152+
// console.dir(Uint8ClampedArray.from(newData));
153+
// array255.data = new Uint8ClampedArray(newData);
154+
newData = Uint8ClampedArray.from(newData);
155+
// console.dir(newData);
156+
// console.groupEnd();
157+
// debugger;
158+
let newImageData = new ImageData(newData, newWidth, newHeight);
159+
// let newImageData = new ImageData(newData,1);
141160
return newImageData;
142161
}

19--Webcam_Fun/js/scripts.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,7 @@ if (navigator.mediaDevices) {
403403
}
404404
console.log('canvasScale: ',canvasScale);
405405
}
406-
fCanvasScale([vWidth,vHeight],[wWidth,wHeight]);
406+
// fCanvasScale([vWidth,vHeight],[wWidth,wHeight]);
407407

408408
canvas.width = wWidth;
409409
canvas.height = wHeight;
@@ -417,8 +417,8 @@ if (navigator.mediaDevices) {
417417
// console.log('canvas.style.transform: ',canvas.style.transform);
418418

419419
/* center the canvas */
420-
positionX = (wWidth - vWidth)/2;
421-
positionY = (wHeight - vHeight)/2;
420+
// positionX = (wWidth - vWidth)/2;
421+
// positionY = (wHeight - vHeight)/2;
422422

423423
let randoms = []; // random numbers
424424
randoms.push(Math.floor(Math.random()*25)+Math.floor(Math.random()*250));
@@ -512,7 +512,7 @@ if (navigator.mediaDevices) {
512512
pixels = fFxPixelate(pixels,intPixelate);
513513
break;
514514
case 'Invert':
515-
// pixels = fFxInvert(pixels);
515+
pixels = fFxInvert(pixels);
516516
break;
517517
}
518518

@@ -738,6 +738,6 @@ window.addEventListener('resize', fMediaQueries);
738738

739739
/* fake UI clicks to open controls */
740740
startStream();
741-
selectFx.selectedIndex = 5;
741+
selectFx.selectedIndex = 6;
742742
toggleFxControls();
743743

0 commit comments

Comments
 (0)