-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathpixelator.html
126 lines (105 loc) · 3.88 KB
/
pixelator.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
126
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
#target {
background: black;
height: 100vh;
width: 100vw;
z-index: -1;
position: fixed;
}
#wrapper {
position: absolute;
right: 0;
width: 300px;
display: flex;
flex-wrap: wrap;
}
#wrapper * {flex-basis: 999px;}
img {display: none; }
</style>
</head>
<body>
<canvas id="target"></canvas>
<div id="wrapper">
<input type="file" name="" id="image-file">
<input type="number" id="image-multiplier" min="0" max="666" value="5" />
<button id="btn">Update</button>
</div>
<img src="veera.png" />
<script type="text/javascript">
// Are you KIDDING me with this type casting?
const canvas = /** @type {HTMLCanvasElement} */ document.querySelector('#target');
const btn = document.querySelector("#btn");
const in_file = document.querySelector("#image-file");
const in_nbr = document.querySelector("#image-multiplier");
let pixelMultiplier = parseInt(in_nbr.value);
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
const ctx = /** @type {CanvasRenderingContext2d} */ canvas.getContext('2d');
const img = document.querySelector('img');
img.addEventListener('load', () => {
let imageHeight = img.height;
let imageWidth = img.width;
// draw centered image
const posX = Math.ceil(canvas.width/2 - imageWidth/2);
const posY = Math.ceil(canvas.height/2 - imageHeight/2);
ctx.drawImage(img, posX, posY, imageWidth, imageHeight);
// read rendered image pixels
const imageData = ctx.getImageData(posX, posY, imageWidth, imageHeight);
const pixelvalues = imageData.data;
// console.log(pixelvalues)
ctx.clearRect(0, 0, canvas.width, canvas.height);
// lööp over image, each 5th pixel
let loopkiller = 100000; // around 100k
for (let row = 1; row < imageHeight; row = row + pixelMultiplier) {
for (let col = 1; col < imageWidth; col = col + pixelMultiplier) {
loopkiller--;
if (loopkiller < 0) { return console.log("killed"); }
// get 1st pixel color
const pixelReference = ((row*imageWidth)+(col))*4;
if (pixelReference === null || typeof pixelReference === "undefined") {return console.log("Invalid pixel reference"); }
const color = `rgb(
${pixelvalues[pixelReference]},
${pixelvalues[pixelReference+1]},
${pixelvalues[pixelReference+2]}
)`;
// +3 would be the alpha channel, which is pointless for us
// console.log(pixelReference, color);
// draw "pixel" ball
ctx.fillStyle = color;
ctx.fillRect(posX + col, posY + row, pixelMultiplier, pixelMultiplier);
}
}
});
btn.addEventListener('click', (e) => {
pixelMultiplier = parseInt(in_nbr.value);
if (pixelMultiplier > 666) {
return alert("thats too much");
} else if (pixelMultiplier < 2) {
return alert("2 or more pls");
}
const file = in_file.files[0];
console.log({ file });
if (file.size > 900000) {
return alert("Use a smaller image pls");
}
const fr = new FileReader();
fr.onload = () => {
img.src = fr.result;
}; // onload fires after reading is complete
fr.readAsDataURL(file); // begin reading
});
</script>
</body>
</html>