2

I have a simple question with a more complicated background. I never worked with imagedata before, so please overlook my greenhorn-imagination of possible solutions.

The question is how I can read imagedata with more than 8 bit per channel, using JavaScript?

I download my image as follows

return new Promise(function (resolve, reject) {

    TESTIMAGE32 = new Image();

    TESTIMAGE32.onload = function () {
        resolve();
    }

    TESTIMAGE32.onerror = function () {
        reject();
    }

    var date = new Date()
    TESTIMAGE32.src = "images/demo/test.png" + "?" + date.getTime()

});

After that I tried to access the image data directly, but only found a soultion, using the canvas api. Probably my problem starts here:

var canvas = document.getElementById("data_canvas")
var ctx = canvas.getContext('2d');
ctx.drawImage(TESTIMAGE32, 0, 0, 50, 50, 0, 0, 50, 50);
const imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);

The canvas api extracted the image data to an 1-D array in the "rgba" pattern on itself and clamped all values to 8 bit. So one pixel is represented by four values

[r1, g1, b1, a1, r2, g2, b2, a2, ...]

Actually I would prefer a monochrome image anyways. The background is, that I have a giant matrix of 100000 x 3000 Pixel and for each pixel I want to store an integer value. Saving this data to an image keeps the data size incredible small compared to a uncompressed binary file. With my current knowledge I could store four numeric values between 0-255 in each image pixel, but this range is too small for my purpose. Thats why I would like to have an mono image with 32bit mono channel to store one value form -2147483648 to 2147483647 in each pixel.

enter image description here

I hope I gave you all the information in an accessible way. Thanks for your help!!

gear
  • 181
  • 1
  • 11
  • You might need to work with 8-bit channels and do the encoding and decoding yourself. – Thomas Feb 18 '22 at 13:28
  • @Thomas I am not sure if I got you right? You mean, that I could split my 32bit number in 4x8bit, save them to an rgba 8-bit image and build my 32bit number again from the rgba values? – gear Feb 18 '22 at 13:31
  • "Saving this data to an image keeps the data size incredible small compared to a **uncompressed** binary file", true because images are compressed. Compressing your data directly would give you better results, and would be a lot easier to work with. Nowadays we even have access to gzip or deflate in the web API directly: https://developer.mozilla.org/en-US/docs/Web/API/Compression_Streams_API – Kaiido Feb 18 '22 at 14:41
  • @Kaiido Thats correct. Unfortunately my data generation happens in C++ and I didnt find a good and quick solution to compress a string and respond to the http request of the frontend. So I decided, to go with image compression, because the matrix is basicly a image – gear Feb 19 '22 at 18:29
  • @Kaiido If the data is actually an image, using an image compression algorithm is likely to yield a smaller file size. – Thomas Feb 19 '22 at 18:45
  • @Thomas the data is apparently just a matrix based dataset. First, they need a lossless format, because they need to retrieve that data exactly. On lossless image formats, webp is kindof the best as their algo will actually modify the source image by clustering similar pixels and rechannelling the colors to reduce the entropy so that the compressor has less work to do. However while this works well for real color images, for raw matrix data (a.k.a. "noise"), this is terrible since there will be no real benefit + bigger headers. So in that case a simple deflate will certainly win. – Kaiido Feb 20 '22 at 02:42

0 Answers0