forked from mutaphysis/smackmyglitchupjs
-
Notifications
You must be signed in to change notification settings - Fork 8
/
glitch.html
125 lines (117 loc) · 4.61 KB
/
glitch.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
<!DOCTYPE html>
<html>
<head>
<title>Smack my glitch up</title>
<style>
html, body {
height: 100%; margin: 0; padding: 0;
overflow: hidden;
}
#canvas {
position: absolute;
/* width: 100%; height: 100%; */
}
</style>
</head>
<body>
<canvas id="canvas" width="704" height="352"></canvas>
<script>
// Thanks to http://www.nczonline.net/blog/2009/12/08/computer-science-in-javascript-base64-encoding/
// Idea from http://blog.soulwire.co.uk/laboratory/flash/as3-bitmapdata-glitch-generator
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var jpgHeaderLength;
var base64Chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
var base64Map = base64Chars.split("");
var reverseBase64Map = {}; base64Map.forEach(function(val, key) { reverseBase64Map[val] = key} );
function detectJpegHeaderSize(data) {
jpgHeaderLength = 417;
for (var i = 0, l = data.length; i < l; i++) {
if (data[i] == 0xFF && data[i+1] == 0xDA) {
//console.log("xxxxxxx<<<<", data[i], data[i+1], i, l);
jpgHeaderLength = i + 2; return;
}
}
}
// base64 is 2^6, byte is 2^8, every 4 base64 values create three bytes
function base64ToByteArray(str) {
var result = [], digitNum, cur, prev;
for (var i = 23, l = str.length; i < l; i++) {
cur = reverseBase64Map[str.charAt(i)];
digitNum = (i-23) % 4;
switch(digitNum){
//case 0: first digit - do nothing, not enough info to work with
case 1: //second digit
result.push(prev << 2 | cur >> 4);
break;
case 2: //third digit
result.push((prev & 0x0f) << 4 | cur >> 2);
break;
case 3: //fourth digit
result.push((prev & 3) << 6 | cur);
break;
}
prev = cur;
}
return result;
}
function byteArrayToBase64(arr) {
var result = ["data:image/jpeg;base64,"], byteNum, cur, prev;
for (var i = 0, l = arr.length; i < l; i++) {
cur = arr[i];
byteNum = i % 3;
switch (byteNum) {
case 0: //first byte
result.push(base64Map[cur >> 2]);
break;
case 1: //second byte
result.push(base64Map[(prev & 3) << 4 | (cur >> 4)]);
break;
case 2: //third byte
result.push(base64Map[(prev & 0x0f) << 2 | (cur >> 6)]);
result.push(base64Map[cur & 0x3f]);
break;
}
prev = cur;
}
if (byteNum == 0) {
result.push(base64Map[(prev & 3) << 4]);
result.push("==");
} else if (byteNum == 1) {
result.push(base64Map[(prev & 0x0f) << 2]);
result.push("=");
}
return result.join("");
}
function glitchJpegBytes(strArr) {
var rnd = Math.floor(jpgHeaderLength + Math.random() * (strArr.length - jpgHeaderLength - 4));
strArr[rnd] = Math.floor(Math.random() * 256);
}
function glitchJpeg() {
var glitchCopy = imgDataArr.slice();
for (var i = 0; i < 10; i++) {
glitchJpegBytes(glitchCopy);
}
var img = new Image();
img.onload = function() {
ctx.drawImage(img, 0, 0);
setTimeout(glitchJpeg, 50);
}
img.src = byteArrayToBase64(glitchCopy);
}
var initialImage = new Image();
var imgDataArr;
initialImage.onload = function() {
ctx.drawImage(initialImage, 0, 0);
var imgData = canvas.toDataURL("image/jpeg");
imgDataArr = base64ToByteArray(imgData);
detectJpegHeaderSize(imgDataArr);
glitchJpeg();
// console.log(imgData.substring(0,30));
// console.log(imgDataArr.slice(0, 30));
// console.log (img.src.substring(0,30));
};
initialImage.src = "./code.jpg";
</script>
</body>
</html>