blob: 7bb2cfbbb737a6b6742f331a0d106c10dbbabb5f [file] [log] [blame]
Alex Perryd5e13572020-02-22 15:15:08 -08001import {CameraImage} from 'y2020/vision/vision_generated';
Alex Perry5f474f22020-02-01 12:14:24 -08002
3export class ImageHandler {
4 private canvas = document.createElement('canvas');
5
6 constructor() {
7 document.body.appendChild(this.canvas);
8 }
9
10 handleImage(data: Uint8Array) {
11 const fbBuffer = new flatbuffers.ByteBuffer(data);
Alex Perryd5e13572020-02-22 15:15:08 -080012 const image = CameraImage.getRootAsCameraImage(fbBuffer);
Alex Perry5f474f22020-02-01 12:14:24 -080013
14 const width = image.cols();
15 const height = image.rows();
16 if (width === 0 || height === 0) {
17 return;
18 }
19 const imageBuffer = new Uint8ClampedArray(width * height * 4); // RGBA
20
21 // Read four bytes (YUYV) from the data and transform into two pixels of
22 // RGBA for canvas
23 for (const j = 0; j < height; j++) {
24 for (const i = 0; i < width; i += 2) {
25 const y1 = image.data((j * width + i) * 2);
26 const u = image.data((j * width + i) * 2 + 1);
27 const y2 = image.data((j * width + i + 1) * 2);
28 const v = image.data((j * width + i + 1) * 2 + 1);
29
30 // Based on https://en.wikipedia.org/wiki/YUV#Converting_between_Y%E2%80%B2UV_and_RGB
31 const c1 = y1 - 16;
32 const c2 = y2 - 16;
33 const d = u - 128;
34 const e = v - 128;
35
36 imageBuffer[(j * width + i) * 4 + 0] = (298 * c1 + 409 * e + 128) >> 8;
37 imageBuffer[(j * width + i) * 4 + 1] =
38 (298 * c1 - 100 * d - 208 * e + 128) >> 8;
39 imageBuffer[(j * width + i) * 4 + 2] = (298 * c1 + 516 * d + 128) >> 8;
40 imageBuffer[(j * width + i) * 4 + 3] = 255;
41 imageBuffer[(j * width + i) * 4 + 4] = (298 * c2 + 409 * e + 128) >> 8;
42 imageBuffer[(j * width + i) * 4 + 5] =
43 (298 * c2 - 100 * d - 208 * e + 128) >> 8;
44 imageBuffer[(j * width + i) * 4 + 6] = (298 * c2 + 516 * d + 128) >> 8;
45 imageBuffer[(j * width + i) * 4 + 7] = 255;
46 }
47 }
48
49 const ctx = this.canvas.getContext('2d');
50
51 this.canvas.width = width;
52 this.canvas.height = height;
53 const idata = ctx.createImageData(width, height);
54 idata.data.set(imageBuffer);
55 ctx.putImageData(idata, 0, 0);
56 }
57
58 getId() {
Alex Perryd5e13572020-02-22 15:15:08 -080059 return CameraImage.getFullyQualifiedName();
Alex Perry5f474f22020-02-01 12:14:24 -080060 }
61}