Coder Social home page Coder Social logo

Comments (14)

photopea avatar photopea commented on September 22, 2024 4

Filtering data is removed and the last 721 bytes of "data" are nonsense. So the first Width*Height*2 bytes are what you need. You can convert it to Uint16Array this way:

var area = img.width * img.height
var nimg = new Uint16Array(area);    // or just  nimg = [];
for(var i=0; i<area; i++)  nimg[i] = (img.data[i*2]<<8) | img.data[i*2+1] ;

from upng.js.

photopea avatar photopea commented on September 22, 2024

Hi Klaus,

your image is a 16-bit image and UPNG.js parses it correctly. The .data array is Uint8Array Typed Array, but it contains the correct 16-bit data (correct bits). The length of .data is 131328 Bytes, and with the area of 256x256 pixels, it corresponds to 2 bytes (16 bits) per pixel.

You can convert it into an array of values between 0 and 65535, by reading pairs of bytes and connecting them together (PNG uses Big Endian). You can create a Uint16Array over the same ArrayBuffer, but JS uses Little Endian, so you have to reorder bytes in each pair.

How else can I help you?

from upng.js.

RSully avatar RSully commented on September 22, 2024

I was about to create an issue for this but found this one.

To me, it would make sense if UPNG handled this correctly. If it sees an image is 16 bits, it should provide Uint16Array instead of Uint8Array and handle the byte order internally. Please re-open this issue for discussion.

from upng.js.

RSully avatar RSully commented on September 22, 2024

Additionally, I have an image that is leading me to some confusion:

Screen Shot 2019-04-01 at 11 00 26

This is a single channel 16 bit image, so there are (1440*721) 1,038,240 16-bit pixels. I don't understand how img.data has a length of 2,077,201 - I would expect 2,076,480.

from upng.js.

photopea avatar photopea commented on September 22, 2024

The number 2,077,201 is 2,076,480 + 721 (height). Each row of pixels in PNG contains an extra byte with filtering method. UPNG "unfilters" data, but we keep it in the same Typed Array, to avoid allocating a new array (if your decompressed image was 3 GB big, allocating extra 3 GB would be a waste of memory).

The property "data" contains the image data. It is accessible as bytes (octets), as it is the usual way of storing digital information in computers. It has nothing to do with color values of pixels - a color information of one pixel can have between 1 bit and 64 bits (8 bytes).

PNG format supports not only 16 bits per sample, but also 1 bit, 2 bits, 4 bits, and 8 bits per sample. There can also be 1, 2, 3 or 4 samples per pixel (combinations of gray and RGB, with and without transparency). If we made 20 special functions, that would return an array of values between 0-1, 0-3, 0-15, 0-255, 0-65535, it would make UPNG quite messy. That is why we provide only UPNG.toRGBA8(), which converts any PNG into RGBA image, 8 bits per sample.

If toRGBA8() is not appropriate for your use case, you can convert it into another structure yourself. Let me know if you need help with it.

from upng.js.

RSully avatar RSully commented on September 22, 2024

I'd definitely appreciate a bit of help.

That makes sense. Is the extra byte (for filtering method) stored at the end or the beginning of each row?

As you said, it would be messy to have lots of functions, but perhaps using a DataView would solve this issue? You could store the data once but allow accessing it in many ways.

from upng.js.

mortac8 avatar mortac8 commented on September 22, 2024

Is it basically the same solution if I want to get 16-bits per channel for my RGBA PNGs? I'm looking for a Uint16Array with indexes containing 16-bit values r,g,b,a,r,g,b,a, ...

This line of code is blowing my mind:
for(var i=0; i<area; i++) nimg[i] = (img.data[i*2]<<8) | img.data[i*2+1] ;

from upng.js.

photopea avatar photopea commented on September 22, 2024

@mortac8 It is just converting big endian 16-bit integers into little-endian.

from upng.js.

RalphCodesTheInternet avatar RalphCodesTheInternet commented on September 22, 2024

Hi Photopea

Thanks for this solution. It has helped me a lot so far!

Unfortunately i'm stuck with the conversion to 16 bit. The resulting image contains only 0's. The 8 bit array before converting does not contain only 0's though. I've tried with several different images and they all result to being 0's.

Would you mind pointing me in the right direction to solve this?

from upng.js.

photopea avatar photopea commented on September 22, 2024

@RalphCodesTheInternet What do you mean by a "conversion"? UPNG.js can not convert between 8 and 16 bit data.

from upng.js.

RalphCodesTheInternet avatar RalphCodesTheInternet commented on September 22, 2024

So basically I get a 16 bit PNG compressed image. The image was compressed by opencv and is sent to my JS side in base64 encoding.

To decode base64 I did the following:

var binary_string = window.atob(message.data); var len = binary_string.length; var bytes = new Uint8Array(len); for (var i = 0; i < len; i++) { bytes[i] = binary_string.charCodeAt(i); }

I removed the header and finally used UPNG to decode the PNG like this:

var without_header = bytes.slice(12,bytes.length); var im = UPNG.decode(without_header);

This essentially yields an 8 bit image like you mentioned before. I tried to convert it to 16 bits like you showed above, but the image then just contains 0 values.

Filtering data is removed and the last 721 bytes of "data" are nonsense. So the first WidthHeight2 bytes are what you need. You can convert it to Uint16Array this way:

var area = img.width * img.height
var nimg = new Uint16Array(area);    // or just  nimg = [];
for(var i=0; i<area; i++)  nimg[i] = (img.data[i*2]<<8) | img.data[i*2+1] ;

from upng.js.

photopea avatar photopea commented on September 22, 2024

UPNG.decode() should contain a 16-bit data in a Uint8Array buffer.

If you need 8-bit RGBA data (e.g. to display it in a HTML5 canvas), use UPNG.toRGBA8(), as described in our manual.

from upng.js.

RalphCodesTheInternet avatar RalphCodesTheInternet commented on September 22, 2024

I do not need to display it in a canvas, I only require the raw 16 bit values of each pixel. Oh yes, and this is a gray scale image, so there is only one channel. I just cant figure out why all the values are 0 if the array returned by UPNG contains actual values.

First console log is UPNG return, second log is the method you described to convert to 16 bit image.

Screenshot_20210922_154539

from upng.js.

photopea avatar photopea commented on September 22, 2024

There are values [18,81,18,81 ... ], these values can not be converted to 0 if yo use my for loop.

(18<<8) | 81   // this is not a zero

from upng.js.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.