formatting

This commit is contained in:
javl
2023-05-02 16:06:59 +02:00
parent 51315c0054
commit 827748286d
+66 -70
View File
@@ -1,31 +1,31 @@
/* eslint-disable no-plusplus */
const bwrPalette = [
[0, 0, 0, 255],
[255, 255, 255, 255],
[255, 0, 0, 255]
]
[255, 0, 0, 255],
];
const bwPalette = [
[0, 0, 0, 255],
[255, 255, 255, 255],
]
];
function dithering(ctx, width, height, threshold, typeIndex) {
const type = ['binary', 'bayer', 'floydsteinberg', 'atkinson'][typeIndex];
const bayerThresholdMap = [
[ 15, 135, 45, 165 ],
[ 195, 75, 225, 105 ],
[ 60, 180, 30, 150 ],
[ 240, 120, 210, 90 ]
[15, 135, 45, 165],
[195, 75, 225, 105],
[60, 180, 30, 150],
[240, 120, 210, 90],
];
const lumR = [];
const lumG = [];
const lumB = [];
for (let i=0; i<256; i++) {
lumR[i] = i*0.299;
lumG[i] = i*0.587;
lumB[i] = i*0.114;
for (let i = 0; i < 256; i++) {
lumR[i] = i * 0.299;
lumG[i] = i * 0.587;
lumB[i] = i * 0.114;
}
const imageData = ctx.getImageData(0, 0, width, height);
@@ -33,50 +33,49 @@ function dithering(ctx, width, height, threshold, typeIndex) {
// Greyscale luminance (sets r pixels to luminance of rgb)
for (let i = 0; i <= imageDataLength; i += 4) {
imageData.data[i] = Math.floor(lumR[imageData.data[i]] + lumG[imageData.data[i+1]] + lumB[imageData.data[i+2]]);
imageData.data[i] =
Math.floor(lumR[imageData.data[i]] + lumG[imageData.data[i + 1]] + lumB[imageData.data[i + 2]]);
}
const w = imageData.width;
let newPixel, err;
let newPixel; let
err;
for (let currentPixel = 0; currentPixel <= imageDataLength; currentPixel+=4) {
if (type ==="binary") {
for (let currentPixel = 0; currentPixel <= imageDataLength; currentPixel += 4) {
if (type === 'binary') {
// No dithering
imageData.data[currentPixel] = imageData.data[currentPixel] < threshold ? 0 : 255;
} else if (type ==="bayer") {
} else if (type === 'bayer') {
// 4x4 Bayer ordered dithering algorithm
var x = currentPixel/4 % w;
var y = Math.floor(currentPixel/4 / w);
var map = Math.floor( (imageData.data[currentPixel] + bayerThresholdMap[x%4][y%4]) / 2 );
// eslint-disable-next-line no-mixed-operators
const x = currentPixel / 4 % w;
const y = Math.floor(currentPixel / 4 / w);
const map = Math.floor((imageData.data[currentPixel] + bayerThresholdMap[x % 4][y % 4]) / 2);
imageData.data[currentPixel] = (map < threshold) ? 0 : 255;
} else if (type ==="floydsteinberg") {
} else if (type === 'floydsteinberg') {
// Floyda€"Steinberg dithering algorithm
newPixel = imageData.data[currentPixel] < 129 ? 0 : 255;
err = Math.floor((imageData.data[currentPixel] - newPixel) / 16);
imageData.data[currentPixel] = newPixel;
imageData.data[currentPixel + 4 ] += err*7;
imageData.data[currentPixel + 4*w - 4 ] += err*3;
imageData.data[currentPixel + 4*w ] += err*5;
imageData.data[currentPixel + 4*w + 4 ] += err*1;
} else if (type ==="atkinson") {
imageData.data[currentPixel + 4] += err * 7;
imageData.data[currentPixel + 4 * w - 4] += err * 3;
imageData.data[currentPixel + 4 * w] += err * 5;
imageData.data[currentPixel + 4 * w + 4] += err * 1;
} else if (type === 'atkinson') {
// Bill Atkinson's dithering algorithm
newPixel = imageData.data[currentPixel] < threshold ? 0 : 255;
err = Math.floor((imageData.data[currentPixel] - newPixel) / 8);
imageData.data[currentPixel] = newPixel;
imageData.data[currentPixel + 4 ] += err;
imageData.data[currentPixel + 8 ] += err;
imageData.data[currentPixel + 4*w - 4 ] += err;
imageData.data[currentPixel + 4*w ] += err;
imageData.data[currentPixel + 4*w + 4 ] += err;
imageData.data[currentPixel + 8*w ] += err;
imageData.data[currentPixel + 4] += err;
imageData.data[currentPixel + 8] += err;
imageData.data[currentPixel + 4 * w - 4] += err;
imageData.data[currentPixel + 4 * w] += err;
imageData.data[currentPixel + 4 * w + 4] += err;
imageData.data[currentPixel + 8 * w] += err;
} else {
console.error("unknown dithering type requested: " + type);
console.error(`unknown dithering type requested: ${type}`);
}
// Set g and b pixels equal to r
@@ -86,8 +85,8 @@ function dithering(ctx, width, height, threshold, typeIndex) {
ctx.putImageData(imageData, 0, 0);
}
function canvas2bytes(canvas, type='bw') {
const ctx = canvas.getContext("2d");
function canvas2bytes(canvas, type = 'bw') {
const ctx = canvas.getContext('2d');
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const arr = [];
@@ -97,9 +96,9 @@ function canvas2bytes(canvas, type='bw') {
for (let y = 0; y < canvas.height; y++) {
const index = (canvas.width * 4 * y) + x * 4;
if (type !== 'bwr') {
buffer.push(imageData.data[index] > 0 && imageData.data[index+1] > 0 && imageData.data[index+2] > 0 ? 1 : 0);
buffer.push(imageData.data[index] > 0 && imageData.data[index + 1] > 0 && imageData.data[index + 2] > 0 ? 1 : 0);
} else {
buffer.push(imageData.data[index] > 0 && imageData.data[index+1] === 0 && imageData.data[index+2] === 0 ? 1 : 0);
buffer.push(imageData.data[index] > 0 && imageData.data[index + 1] === 0 && imageData.data[index + 2] === 0 ? 1 : 0);
}
if (buffer.length === 8) {
@@ -115,7 +114,7 @@ function getColorDistance(rgba1, rgba2) {
const [r1, b1, g1] = rgba1;
const [r2, b2, g2] = rgba2;
const rm = (r1 + r2 ) / 2;
const rm = (r1 + r2) / 2;
const r = r1 - r2;
const g = g1 - g2;
@@ -140,31 +139,28 @@ function getNearColor(pixel, palette) {
return palette[paletteIndex];
}
function getNearColorV2(color, palette) {
let minDistanceSquared = 255*255 + 255*255 + 255*255 + 1;
let minDistanceSquared = 255 * 255 + 255 * 255 + 255 * 255 + 1;
let bestIndex = 0;
for (let i = 0; i < palette.length; i++) {
let rdiff = (color[0] & 0xff) - (palette[i][0] & 0xff);
let gdiff = (color[1] & 0xff) - (palette[i][1] & 0xff);
let bdiff = (color[2] & 0xff) - (palette[i][2] & 0xff);
let distanceSquared = rdiff*rdiff + gdiff*gdiff + bdiff*bdiff;
const rdiff = (color[0] & 0xff) - (palette[i][0] & 0xff);
const gdiff = (color[1] & 0xff) - (palette[i][1] & 0xff);
const bdiff = (color[2] & 0xff) - (palette[i][2] & 0xff);
const distanceSquared = rdiff * rdiff + gdiff * gdiff + bdiff * bdiff;
if (distanceSquared < minDistanceSquared) {
minDistanceSquared = distanceSquared;
bestIndex = i;
}
}
return palette[bestIndex];
}
function updatePixel(imageData, index, color) {
imageData[index] = color[0];
imageData[index+1] = color[1];
imageData[index+2] = color[2];
imageData[index+3] = color[3];
imageData[index + 1] = color[1];
imageData[index + 2] = color[2];
imageData[index + 3] = color[3];
}
function getColorErr(color1, color2, rate) {
@@ -177,8 +173,8 @@ function getColorErr(color1, color2, rate) {
function updatePixelErr(imageData, index, err, rate) {
imageData[index] += err[0] * rate;
imageData[index+1] += err[1] * rate;
imageData[index+2] += err[2] * rate;
imageData[index + 1] += err[1] * rate;
imageData[index + 2] += err[2] * rate;
}
function ditheringCanvasByPalette(canvas, palette, type) {
@@ -188,27 +184,27 @@ function ditheringCanvasByPalette(canvas, palette, type) {
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const w = imageData.width;
for (let currentPixel = 0; currentPixel <= imageData.data.length; currentPixel+=4) {
const newColor = getNearColorV2(imageData.data.slice(currentPixel, currentPixel+4), palette);
for (let currentPixel = 0; currentPixel <= imageData.data.length; currentPixel += 4) {
const newColor = getNearColorV2(imageData.data.slice(currentPixel, currentPixel + 4), palette);
if (type === "bwr_floydsteinberg") {
const err = getColorErr(imageData.data.slice(currentPixel, currentPixel+4), newColor, 16);
if (type === 'bwr_floydsteinberg') {
const err = getColorErr(imageData.data.slice(currentPixel, currentPixel + 4), newColor, 16);
updatePixel(imageData.data, currentPixel, newColor);
updatePixelErr(imageData.data, currentPixel +4, err, 7);
updatePixelErr(imageData.data, currentPixel + 4*w - 4, err, 3);
updatePixelErr(imageData.data, currentPixel + 4*w, err, 5);
updatePixelErr(imageData.data, currentPixel + 4*w + 4, err, 1);
updatePixelErr(imageData.data, currentPixel + 4, err, 7);
updatePixelErr(imageData.data, currentPixel + 4 * w - 4, err, 3);
updatePixelErr(imageData.data, currentPixel + 4 * w, err, 5);
updatePixelErr(imageData.data, currentPixel + 4 * w + 4, err, 1);
} else {
const err = getColorErr(imageData.data.slice(currentPixel, currentPixel+4), newColor, 8);
const err = getColorErr(imageData.data.slice(currentPixel, currentPixel + 4), newColor, 8);
updatePixel(imageData.data, currentPixel, newColor);
updatePixelErr(imageData.data, currentPixel +4, err, 1);
updatePixelErr(imageData.data, currentPixel +8, err, 1);
updatePixelErr(imageData.data, currentPixel +4 * w - 4, err, 1);
updatePixelErr(imageData.data, currentPixel +4 * w, err, 1);
updatePixelErr(imageData.data, currentPixel +4 * w + 4, err, 1);
updatePixelErr(imageData.data, currentPixel +8 * w, err, 1);
updatePixelErr(imageData.data, currentPixel + 4, err, 1);
updatePixelErr(imageData.data, currentPixel + 8, err, 1);
updatePixelErr(imageData.data, currentPixel + 4 * w - 4, err, 1);
updatePixelErr(imageData.data, currentPixel + 4 * w, err, 1);
updatePixelErr(imageData.data, currentPixel + 4 * w + 4, err, 1);
updatePixelErr(imageData.data, currentPixel + 8 * w, err, 1);
}
}
ctx.putImageData(imageData, 0, 0);