update image-q and other packages
This commit is contained in:
parent
9401cde3ce
commit
44af557581
|
@ -6,7 +6,7 @@
|
|||
import React, { useState, useEffect } from 'react';
|
||||
import { useSelector, shallowEqual } from 'react-redux';
|
||||
import fileDownload from 'js-file-download';
|
||||
import { utils, applyPalette } from 'image-q';
|
||||
import iq from 'image-q';
|
||||
import { jt, t } from 'ttag';
|
||||
|
||||
import printGIMPPalette from '../core/exportGPL';
|
||||
|
@ -43,6 +43,113 @@ function readFile(
|
|||
fr.readAsDataURL(file);
|
||||
}
|
||||
|
||||
const ColorDistanceCalculators = [
|
||||
'Euclidean',
|
||||
'Manhattan',
|
||||
'CIEDE2000',
|
||||
'CIE94Textiles',
|
||||
'CIE94GraphicArts',
|
||||
'EuclideanBT709NoAlpha',
|
||||
'EuclideanBT709',
|
||||
'ManhattanBT709',
|
||||
'CMetric',
|
||||
'PNGQuant',
|
||||
'ManhattanNommyde',
|
||||
];
|
||||
|
||||
function quantize(
|
||||
pointContainer,
|
||||
colors,
|
||||
colorDist,
|
||||
strategy,
|
||||
onProgress,
|
||||
) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// read colors into palette
|
||||
const palette = new iq.utils.Palette();
|
||||
palette.add(iq.utils.Point.createByRGBA(0, 0, 0, 0));
|
||||
colors.forEach((clr) => {
|
||||
const [r, g, b] = clr;
|
||||
const point = iq.utils.Point.createByRGBA(r, g, b, 255);
|
||||
palette.add(point);
|
||||
});
|
||||
// construct color distance calculator
|
||||
let distance;
|
||||
switch (colorDist) {
|
||||
case 'Euclidean':
|
||||
distance = new iq.distance.Euclidean();
|
||||
break;
|
||||
case 'Manhattan':
|
||||
distance = new iq.distance.Manhattan();
|
||||
break;
|
||||
case 'CIEDE2000':
|
||||
distance = new iq.distance.CIEDE2000();
|
||||
break;
|
||||
case 'CIE94Textiles':
|
||||
distance = new iq.distance.CIE94Textiles();
|
||||
break;
|
||||
case 'CIE94GraphicArts':
|
||||
distance = new iq.distance.CIE94GraphicArts();
|
||||
break;
|
||||
case 'EuclideanBT709NoAlpha':
|
||||
distance = new iq.distance.EuclideanBT709NoAlpha();
|
||||
break;
|
||||
case 'EuclideanBT709':
|
||||
distance = new iq.distance.EuclideanBT709();
|
||||
break;
|
||||
case 'ManhattanBT709':
|
||||
distance = new iq.distance.ManhattanBT709();
|
||||
break;
|
||||
case 'CMetric':
|
||||
distance = new iq.distance.CMetric();
|
||||
break;
|
||||
case 'PNGQuant':
|
||||
distance = new iq.distance.PNGQuant();
|
||||
break;
|
||||
case 'ManhattanNommyde':
|
||||
distance = new iq.distance.ManhattanNommyde();
|
||||
break;
|
||||
default:
|
||||
distance = new iq.distance.Euclidean();
|
||||
}
|
||||
// construct image quantizer
|
||||
let imageQuantizer;
|
||||
if (strategy === 'Nearest') {
|
||||
imageQuantizer = new iq.image.NearestColor(distance);
|
||||
} else if (strategy === 'Riemersma') {
|
||||
imageQuantizer = new iq.image.ErrorDiffusionRiemersma(distance);
|
||||
} else {
|
||||
imageQuantizer = new iq.image.ErrorDiffusionArray(
|
||||
distance,
|
||||
iq.image.ErrorDiffusionArrayKernel[strategy],
|
||||
true,
|
||||
0,
|
||||
false,
|
||||
);
|
||||
}
|
||||
// quantize
|
||||
let outPointContainer;
|
||||
const iterator = imageQuantizer.quantize(pointContainer, palette);
|
||||
const next = () => {
|
||||
try {
|
||||
const result = iterator.next();
|
||||
if (result.done) {
|
||||
resolve(outPointContainer);
|
||||
} else {
|
||||
if (result.value.pointContainer) {
|
||||
outPointContainer = result.value.pointContainer;
|
||||
}
|
||||
if (onProgress) onProgress(result.value.progress);
|
||||
setTimeout(next, 10);
|
||||
}
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
};
|
||||
setTimeout(next, 10);
|
||||
});
|
||||
}
|
||||
|
||||
function drawPixels(idxi8, width, height) {
|
||||
const can = document.createElement('canvas');
|
||||
can.width = width;
|
||||
|
@ -155,28 +262,23 @@ async function renderOutputImage(opts) {
|
|||
height,
|
||||
aa,
|
||||
);
|
||||
pointContainer = utils.PointContainer.fromHTMLCanvasElement(image);
|
||||
pointContainer = iq.utils.PointContainer.fromHTMLCanvasElement(image);
|
||||
} else {
|
||||
pointContainer = utils.PointContainer.fromHTMLImageElement(image);
|
||||
pointContainer = iq.utils.PointContainer.fromHTMLImageElement(image);
|
||||
}
|
||||
// dither
|
||||
const { colors, strategy, colorDist } = dither;
|
||||
const palette = new utils.Palette();
|
||||
palette.add(utils.Point.createByRGBA(0, 0, 0, 0));
|
||||
colors.forEach((clr) => {
|
||||
const [r, g, b] = clr;
|
||||
const point = utils.Point.createByRGBA(r, g, b, 255);
|
||||
palette.add(point);
|
||||
});
|
||||
const progEl = document.getElementById('qprog');
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
pointContainer = await applyPalette(pointContainer, palette, {
|
||||
colorDistanceFormula: colorDist,
|
||||
imageQuantization: strategy,
|
||||
onProgress: (progress) => {
|
||||
pointContainer = await quantize(
|
||||
pointContainer,
|
||||
colors,
|
||||
colorDist,
|
||||
strategy,
|
||||
(progress) => {
|
||||
progEl.innerHTML = `Loading... ${Math.round(progress)} %`;
|
||||
},
|
||||
});
|
||||
);
|
||||
progEl.innerHTML = 'Done';
|
||||
image = drawPixels(
|
||||
pointContainer.toUint8Array(),
|
||||
|
@ -220,8 +322,8 @@ function Converter() {
|
|||
|
||||
const [selectedCanvas, selectCanvas] = useState(canvasId);
|
||||
const [selectedFile, selectFile] = useState(null);
|
||||
const [selectedStrategy, selectStrategy] = useState('nearest');
|
||||
const [selectedColorDist, selectColorDist] = useState('euclidean');
|
||||
const [selectedStrategy, selectStrategy] = useState('Nearest');
|
||||
const [selectedColorDist, selectColorDist] = useState('Euclidean');
|
||||
const [selectedScaleKeepRatio, selectScaleKeepRatio] = useState(true);
|
||||
const [scaleData, setScaleData] = useState({
|
||||
enabled: false,
|
||||
|
@ -236,8 +338,6 @@ function Converter() {
|
|||
offsetY: 0,
|
||||
});
|
||||
|
||||
const input = document.createElement('canvas');
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedFile) {
|
||||
const canvas = canvases[selectedCanvas];
|
||||
|
@ -346,21 +446,14 @@ function Converter() {
|
|||
}}
|
||||
>
|
||||
{
|
||||
['nearest',
|
||||
'riemersma',
|
||||
'floyd-steinberg',
|
||||
'false-floyd-steinberg',
|
||||
'stucki',
|
||||
'atkinson',
|
||||
'jarvis',
|
||||
'burkes',
|
||||
'sierra',
|
||||
'two-sierra',
|
||||
'sierra-lite'].map((strat) => (
|
||||
<option
|
||||
value={strat}
|
||||
selected={(selectedStrategy === strat)}
|
||||
>{strat}</option>
|
||||
['Nearest',
|
||||
'Riemersma',
|
||||
...Object.keys(iq.image.ErrorDiffusionArrayKernel),
|
||||
].map((strat) => (
|
||||
<option
|
||||
value={strat}
|
||||
selected={(selectedStrategy === strat)}
|
||||
>{strat}</option>
|
||||
))
|
||||
}
|
||||
</select>
|
||||
|
@ -373,21 +466,11 @@ function Converter() {
|
|||
}}
|
||||
>
|
||||
{
|
||||
['cie94-textiles',
|
||||
'cie94-graphic-arts',
|
||||
'ciede2000',
|
||||
'color-metric',
|
||||
'euclidean',
|
||||
'euclidean-bt709-noalpha',
|
||||
'euclidean-bt709',
|
||||
'manhattan',
|
||||
'manhattan-bt709',
|
||||
'manhattan-nommyde',
|
||||
'pngquant'].map((strat) => (
|
||||
<option
|
||||
value={strat}
|
||||
selected={(selectedColorDist === strat)}
|
||||
>{strat}</option>
|
||||
ColorDistanceCalculators.map((strat) => (
|
||||
<option
|
||||
value={strat}
|
||||
selected={(selectedColorDist === strat)}
|
||||
>{strat}</option>
|
||||
))
|
||||
}
|
||||
</select>
|
||||
|
|
Loading…
Reference in New Issue
Block a user