Optimise dither
This commit is contained in:
+3
-17
@@ -1,7 +1,7 @@
|
||||
|
||||
import React from "react";
|
||||
import { ImportOutput, MuralOld, RGB } from "../interfaces";
|
||||
import { canvasToImageData, convertOldMuralToNewMural, createMuralExtended, getColorScore, getExtension,
|
||||
import { canvasToImageData, convertOldMuralToNewMural, createClosestIndexColor, createMuralExtended, getColorScore, getExtension,
|
||||
imageDataToPaletteIndices, imageToCanvas, loadImageSource, processNumberEvent,
|
||||
readAsArrayBuffer,
|
||||
readAsDataUrl, readAsString, resize, rgb } from "../lib/utils";
|
||||
@@ -440,13 +440,13 @@ function quantizeImage(
|
||||
}
|
||||
|
||||
export function flatQuantizeImageData(imageData: ImageData, palette: Palette) {
|
||||
const indexColor = createClosestIndexColor(palette.palette);
|
||||
for (let i = 0; i < imageData.data.length; i += 4) {
|
||||
const r = imageData.data[i + 0] ?? 0;
|
||||
const g = imageData.data[i + 1] ?? 0;
|
||||
const b = imageData.data[i + 2] ?? 0;
|
||||
const a = imageData.data[i + 3] ?? 0;
|
||||
const obj = rgb(r, g, b);
|
||||
const index = findClosestIndexColor(obj, palette);
|
||||
const index = indexColor(r, g, b);
|
||||
const color = palette.palette[index];
|
||||
if (!color) throw new Error(`Unknown color index ${index}`);
|
||||
imageData.data[i + 0] = color.r;
|
||||
@@ -456,20 +456,6 @@ export function flatQuantizeImageData(imageData: ImageData, palette: Palette) {
|
||||
}
|
||||
}
|
||||
|
||||
export function findClosestIndexColor(rgbO: RGB, palette: Palette) {
|
||||
const scores: number[] = [];
|
||||
|
||||
for (const rgb of palette.palette) {
|
||||
const r = getColorScore(rgbO.r, rgb.r);
|
||||
const g = getColorScore(rgbO.g, rgb.g);
|
||||
const b = getColorScore(rgbO.b, rgb.b);
|
||||
scores.push(r + g + b);
|
||||
}
|
||||
const lowest = Math.min(...scores);
|
||||
const index = scores.indexOf(lowest);
|
||||
return index;
|
||||
}
|
||||
|
||||
export function imageDataToCanvas(imageData: ImageData) {
|
||||
const canvas = document.createElement("canvas");
|
||||
const ctx = canvas.getContext("2d")!;
|
||||
|
||||
+22
-3
@@ -224,13 +224,13 @@ export function canvasToImageData(canvas: HTMLCanvasElement) {
|
||||
}
|
||||
|
||||
export function flatQuantizeImageData(imageData: ImageData, palette: RGB[]) {
|
||||
const indexColor = createClosestIndexColor(palette);
|
||||
for (let i = 0; i < imageData.data.length; i += 4) {
|
||||
const r = imageData.data[i + 0] ?? 0;
|
||||
const g = imageData.data[i + 1] ?? 0;
|
||||
const b = imageData.data[i + 2] ?? 0;
|
||||
const a = imageData.data[i + 3] ?? 0;
|
||||
const obj = rgb(r, g, b);
|
||||
const index = findClosestIndexColor(obj, palette);
|
||||
const index = indexColor(r, g, b);
|
||||
const color = palette[index];
|
||||
if (!color) throw new Error(`Unknown color index ${index}`);
|
||||
imageData.data[i + 0] = color.r;
|
||||
@@ -273,6 +273,7 @@ export async function getPixelStatusMural(mural: Mural, palette: RGB[]): Promise
|
||||
export function imageDataToPaletteIndices(imageData: ImageData, palette: RGB[]) {
|
||||
const { height, width } = imageData;
|
||||
let k = 0;
|
||||
const indexColor = createClosestIndexColor(palette);
|
||||
const pixels = new Int8Array(height * width);
|
||||
for (let i = 0; i < imageData.data.length; i += 4) {
|
||||
const r = imageData.data[i + 0] ?? 0;
|
||||
@@ -282,7 +283,7 @@ export function imageDataToPaletteIndices(imageData: ImageData, palette: RGB[])
|
||||
if (a < 25) {
|
||||
pixels[k++] = -1;
|
||||
} else {
|
||||
const index = findClosestFormArray(rgb(r, g, b), palette);
|
||||
const index = indexColor(r, g, b);
|
||||
pixels[k++] = index;
|
||||
}
|
||||
}
|
||||
@@ -381,6 +382,24 @@ export function createMuralExtended(mural: Mural, palette: string[]): MuralEx {
|
||||
};
|
||||
}
|
||||
|
||||
export function createClosestIndexColor(palette: RGB[]) {
|
||||
const scores = new Uint16Array(palette.length);
|
||||
let lowest = Number.MAX_SAFE_INTEGER;
|
||||
return (r: number, g: number, b: number) => {
|
||||
lowest = Number.MAX_SAFE_INTEGER;
|
||||
for (let i = 0; i < palette.length; i++) {
|
||||
const rgb = palette[i];
|
||||
const rr = getColorScore(r, rgb.r);
|
||||
const gg = getColorScore(g, rgb.g);
|
||||
const bb = getColorScore(b, rgb.b);
|
||||
const value = rr + gg + bb;
|
||||
lowest = lowest < value ? lowest : value;
|
||||
scores[i] = value;
|
||||
}
|
||||
return scores.indexOf(lowest);
|
||||
};
|
||||
}
|
||||
|
||||
let numberFormatter: Intl.NumberFormat;
|
||||
try {
|
||||
const userLocale = navigator.language || (navigator as any).userLanguage;
|
||||
|
||||
Reference in New Issue
Block a user