explorata/src/modules/picture.js

80 lines
2.4 KiB
JavaScript

import { Cell } from "./cell.js";
// https://stackoverflow.com/questions/21646738/convert-hex-to-rgba
// [
function hexToRGB(hex) {
return [
parseInt(hex.slice(1, 3), 16),
parseInt(hex.slice(3, 5), 16),
parseInt(hex.slice(5, 7), 16),
];
}
// https://stackoverflow.com/questions/4492385/convert-simple-array-into-two-dimensional-array-matrix
// convert a 1D array into a 2D matrix
export function toMatrix(array, width) {
return array.reduce(
(rows, key, index) =>
(index % width == 0
? rows.push([key])
: rows[rows.length - 1].push(key)) && rows,
[]
);
}
// convert an image into a black and white image
export function picToBlackAndWhite(pixels, width, height) {
return pixels.reduce((acc, pixel, index) => {
if (index % 4 == 0) {
const count = pixels[index] + pixels[index + 1] + pixels[index + 2];
const colour = count >= 255 ? 255 : 1;
acc.data[index] = colour;
acc.data[index + 1] = colour;
acc.data[index + 2] = colour;
acc.data[index + 3] = 255;
}
return acc;
}, new ImageData(width, height));
}
// convert an ImageData into a 2D array of boolean (0, 1) values
export function picToBoard(pixels) {
return pixels.reduce((acc, pixel, index) => {
const i = index * 4;
const count = pixels[i] + pixels[i + 1] + pixels[i + 2];
const value = (count >= 255) & 1;
acc[index] = new Cell(value);
return acc;
}, []);
}
// convert board to ImageData
// TODO : different cell to color functions
// (binary, intermediate states, camaieux, etc)
export function boardToPic(board, frame) {
const live = board.cellProperties.liveColor;
const dead = board.cellProperties.deadColor;
const img = frame || new ImageData(board.width, board.height);
const colors = [hexToRGB(live), hexToRGB(dead)];
board.grid.reduce((acc, cell, index) => {
if (cell.state === cell.prevState) return acc;
const color = colors[(cell.state === 1) & 1];
const i = index * 4;
acc[i] = color[0];
acc[i + 1] = color[1];
acc[i + 2] = color[2];
acc[i + 3] = 255;
return acc;
}, img.data);
return img;
}
// https://stackoverflow.com/questions/3332237/image-resizing-algorithm
export function scaleToTargetSize(w1, h1, w2, h2) {
const sourceRatio = w1 / h1;
const targetRatio = w2 / h2;
if (sourceRatio > targetRatio) {
return [w2, w2 / sourceRatio];
}
return [h2 * sourceRatio, h2];
}