blocky-6502/index.html

114 lines
3.6 KiB
HTML
Raw Normal View History

2023-06-28 22:52:09 +00:00
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Block video encoding test</title>
<style type="text/css">
.stretchy {
width:267px;
2023-07-03 03:58:19 +00:00
height: 160px;
2023-06-28 22:52:09 +00:00
object-fit: fill;
image-rendering: pixelated;
}
</style>
</head>
<body>
<h1>Block video encoding test</h1>
<h2>Source video</h2>
<div>
<video id="source" src="llamigos.webm" class="stretchy" muted controls playsinline></video>
</div>
<h2>Work canvas</h2>
<div>
2023-07-03 03:58:19 +00:00
<canvas id="work" width="80" height="160" class="stretchy"></canvas>
2023-06-28 22:52:09 +00:00
</div>
<script type="text/javascript">
let width = 80;
2023-07-03 03:58:19 +00:00
let height = 160;
let blockWidth = 2;
let blockHeight = 8;
let widthBlocks = width / blockWidth;
let heightBlocks = height / blockHeight;
2023-06-28 22:52:09 +00:00
function fromSRGB(val) {
if (val <= 0.04045) {
2023-07-03 03:58:19 +00:00
return val / 12.92;
2023-06-28 22:52:09 +00:00
}
2023-07-03 03:58:19 +00:00
return ((val + 0.055) / 1.055) ** 2.4;
2023-06-28 22:52:09 +00:00
}
function toSRGB(val) {
if (val <= 0.0031308) {
2023-07-03 03:58:19 +00:00
return val * 12.92;
2023-06-28 22:52:09 +00:00
}
2023-07-03 03:58:19 +00:00
return (val * 1.055) ** (1.0 / 2.4) - 0.055;
2023-06-28 22:52:09 +00:00
}
function luma(r, g, b) {
return r * 0.299 + g * 0.586 + b * 0.114;
}
function update() {
let ctx = work.getContext('2d');
2023-07-03 03:58:19 +00:00
let pixels = new Uint8Array(width * height);
// Extract the luma
2023-06-28 22:52:09 +00:00
ctx.drawImage(source, 0, 0);
let bits = ctx.getImageData(0, 0, width, height);
let data = bits.data;
for (let y = 0; y < height; y++) {
for (let x = 0; x < width; x++) {
2023-07-03 03:58:19 +00:00
let i = y * width + x;
2023-06-28 22:52:09 +00:00
2023-07-03 03:58:19 +00:00
let r = fromSRGB(data[i * 4] / 255);
let g = fromSRGB(data[i * 4 + 1] / 255);
let b = fromSRGB(data[i * 4 + 2] / 255);
let grayLinear = luma(r, g, b);
let gray = toSRGB(grayLinear);
let gray16 = Math.round(gray * 15);
pixels[i] = gray16;
}
}
2023-06-28 22:52:09 +00:00
2023-07-03 03:58:19 +00:00
let blocks = [];
for (let y = 0; y < height / blockHeight; y++) {
for (let x = 0; x < width / blockWidth; x++) {
let i = y * (width / blockWidth) + x;
}
}
2023-06-28 22:52:09 +00:00
2023-07-03 03:58:19 +00:00
for (let y = 0; y < height; y++) {
for (let x = 0; x < width; x++) {
let i = y * width + x;
let gray16 = pixels[i];
let gray256 = Math.round(gray16 * 255 / 15);
data[i * 4] = gray256;
data[i * 4 + 1] = gray256;
data[i * 4 + 2] = gray256;
2023-06-28 22:52:09 +00:00
}
}
ctx.putImageData(bits, 0, 0);
}
let timer = null;
source.addEventListener('playing', () => {
if (!timer) {
timer = setInterval(update, 1000 / 24);
}
update();
});
source.addEventListener('pause', () => {
if (timer) {
clearInterval(timer);
timer = null;
}
});
</script>
</body>
</html>