ibezkrovnyi / image-quantization

Image Quantization Library with alpha support (based on https://github.com/leeoniya/RgbQuant.js, https://github.com/timoxley/neuquant and http://www.ece.mcmaster.ca/~xwu/cq.c)
141 stars 11 forks source link

buildPalette returning empty data on 3.0.4 #88

Closed variant-tech closed 2 years ago

variant-tech commented 2 years ago

Hi, i have an issue with buildPalette on the latest release of image-q. This is the code that I have, and buildConfig + applyConfig is just an object that contains options for vcolorDistanceFormula, colors, imageQuantization etc.

const inPointContainer = .utils.PointContainer.fromHTMLImageElement(image)

const palette = await buildPalette([inPointContainer], buildConfig);

const outPointContainer = await applyPalette(inPointContainer, palette, applyConfig);

and then it returns an error that says the following

point.js:74 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'r') at Point.from (point.js:74) at ErrorDiffusionArray.quantize (array.js:99) at quantize.next () at next (basicAPI.js:73)

The var palette returns pretty much an empty Palette object, even though inPointContainer is valid and has rgba data. If you can look into the bug (in case it's a source code issue) that'd be great, happy to provide more info as well!

ibezkrovnyi commented 2 years ago

Hi, I think this issue is related to the issue https://github.com/ibezkrovnyi/image-quantization/issues/95 which was fixed today, could you please try image-q@4.0.0 and let me know if your case is fixed too. Thanks

birdlavv commented 2 years ago

Still experiencing the same error in 4.0.0 Reproduction URL: https://codesandbox.io/s/88-reproduction-qensi

ibezkrovnyi commented 2 years ago

Thank you for Reproduction URL.

Atm decoding compressed images is non-goal for image-q project and need to be done with 3rd party library (e.g. pngjs or any other lib) or with help of browser.

The following line expects uncompressed array of 4 byte groups - one group of [r,g,b,a] per each pixel. So, it expects 270x310x4 bytes.

utils.PointContainer.fromBuffer(imageData, 270, 310)

It is useful when you already have uncompressed data, e.g. data comes from canvasContext2d.getImageData, etc.

Example how to process PNG in nodejs (just to show the idea):

https://github.com/ibezkrovnyi/image-quantization/blob/d1a4ac4a3b00c456737a03909b1bb523c569da25/packages/usage-examples/apply-palette-from-file/index.js#L1-L55

Example how to process any format Browser understands (reading from HTMLImageElement):

https://github.com/ibezkrovnyi/image-quantization/blob/d1a4ac4a3b00c456737a03909b1bb523c569da25/packages/demo/src/controller/usage.ts#L84

Example how to process any format Browser understands (manually fetching compressed image):

slightly modified Reproduction URL


import axios from "axios";
import { applyPalette, utils } from "image-q";
(async () => {
const {
data
} = await axios.get(
"https://en.wikipedia.org/static/images/project-logos/enwiki-2x.png",
{ responseType: "arraybuffer" }
);

const image = new Image(); image.onload = async () => { const pointContainer = utils.PointContainer.fromHTMLImageElement(image);

const palette = new utils.Palette(); // https://github.com/ibezkrovnyi/image-quantization/issues/48
palette.add(utils.Point.createByRGBA(0, 0, 0, 255)); // black
palette.add(utils.Point.createByRGBA(255, 255, 255, 255)); // white
const outputPointContainer = await applyPalette(pointContainer, palette, {
  imageQuantization: "floyd-steinberg" // optional
});
console.log(outputPointContainer);

}; const base64 = btoa( Array.from(new Uint8Array(data)) .map((b) => String.fromCharCode(b)) .join("") ); image.src = data:image/png;base64,${base64};

// Original image document.body.appendChild(image); })();

variant-tech commented 2 years ago

Hi @ibezkrovnyi , confirming that issue is fixed on our end with 4.0.0. Thanks for the support!