#seriousgame #tablette #recherche #crowdsourcing #cerveau
Parcourir le cerveau humain dans le navigateur.
my_brain.nii
Nifti-1
189103818504886
base 10 👉 base 2
00000000 = 0
11111111 = 255
3 x 8 bits = 24 bits
16,777,216 valeurs possibles
111011111001001000011100100010110101000011111001
2391462813980249
0000000000000000 = 0
1111111111111111 = 65535
111011111001001000011100100010110101000011111001
61330730720729
Une chaine binaire n'a pas de signification en soi.
const buffer = new ArrayBuffer(byteLength);
001100100100010100000101010011100101011010101011
const view = new Uint8Array(buffer);
00110010 01000101 00000101 01001110 01010110 10101011
[50, 69, 5, 78, 86, 171]
const view = new Uint16Array(buffer);
0011001001000101 0000010101001110 0101011010101011
[12869, 1358, 22187]
view[0] = 255;
11111111 01000101 00000101 01001110 01010110 10101011
view[0] = 546;
546 = 1000100010
view[0] === 34;
Int8Array, Float32Array, Uint8ClampedArray, Uint32Array, ...
new Uint8Array(buffer, 2, 4);
new DataView(buffer).setInt16(42, 1337);
ArrayBuffer.slice(0, 352);
// Create a unsigned int
$buffer = pack("S*", 61330, 7307, 20729);
// string(6)
// Read as 16bit unsigned integers
$values = unpack("S*", $buffer);
// [61330, 7307, 20729]
const request = new XMLHttpRequest();
request.responseType = 'arraybuffer';
request.open('GET', 'http://my.brain.com/my_brain.nii');
request.addEventListener('load', () => {
const buffer = request.response;
});
request.send();
const file = document.getElementById('my-file').files[0];
const buffer = new FileReader().readAsArrayBuffer(file);
const socket = new WebSocket('ws://localhost');
socket.binaryType = 'arraybuffer';
socket.send(buffer);
// ---
socket.on('message', (event) => { const buffer = event.data; })
40 | Nombre de dimensions: 3 (ou 4 👽) |
42 44 46 | Largeur, hauteur et profondeur |
70 72 | DataType et Nombre de bit par voxel |
... | Information d'échelles, description, etc. |
const header = new DataView(buffer, 0, 352);
const width = header.getUint16(42); // 256
const height = header.getUint16(44); // 256
const depth = header.getUint16(46); // 176
const dataType = header.getUint16(70); // 16 (Float32Array)
const bitPerVoxel = header.getUint16(72); // 32
Suite de voxel.
const size = 352 + (length * width * depth) * (bitPerVoxel / 8);
11 534 336 voxels
46 137 696 octets = 46,1 Mo
const body = new Float32Array(buffer, 352);
function getVoxelValue(x, y, z) {
const index = x + (y * width) + (z * width * height);
return body[index];
}
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
const slice = new ImageData(width, height);
function setPixelValue(x, y, intensity) {
const index = 4 * (x + y * width);
const value = Math.round(intensity * 255);
slice.data.fill([value, value, value, 255], index); // R, G, B, A
}
setPixelValue(50, 100, getVoxelValue(50, 100, 32));
context.putImageData(slice);
{ "event": "position", "id": 19, "x": 125, "y": 158 }
[event sur 1 octet][id sur 1 octet][x sur 2 octets][y sur 2 octets]
Javascript gère bien le binaire 👌