jimp-dev / jimp

An image processing library written entirely in JavaScript for Node, with zero external or native dependencies.
http://jimp-dev.github.io/jimp/
MIT License
13.97k stars 762 forks source link

Jimp browser convert my 16 bit grayscale into 8bit RGBA #988

Open remmel opened 3 years ago

remmel commented 3 years ago

Jimp browser convert my 16 bit grayscale into 8 bit RGBA image (8x4=32 bits) because R=G=B= my original gray, quality is lost as my gray was in 16 bits but R or G or B are in 8 bits. The convertion made by jimp is >> 8

The tested image is PNG: 640x480 16 bit grayscale ImageMagick:

$ identify 1305031468.188327.png
1305031468.188327.png PNG 640x480 640x480+0+0 16-bit Grayscale Gray 131604B 0.000u 0:00.000

Expected Behavior

jimpSrc.bitmap.data=Uint8Array(614400) [0, 0, 0, 0, 32, 21, 32, 21, 34, 137,...] or jimpSrc.bitmap.data=Uint16Array(307200) [0, 0, 8213, 8213, 8841, ...] (32*256+21=8213 for the 3rd pixel)

Current Behavior

jimpSrc.bitmap.data=Uint8Array(1228800) [0, 0, 0, 255, 0, 0, 0, 255, 32, 32, 32, 255, 32, 32, 32, 255, ...] with thus R=G=B=my_gray>>8 and A=255 And thus for the 3rd pixel 32<<8=8192 != 8213

Steps to Reproduce

https://jsfiddle.net/remmel/yvmketx0/

<script src="https://unpkg.com/jimp@0.16.1/browser/lib/jimp.js"></script>
var jimpSrc = await Jimp.read("https://uc89daeff68107502f68265ef5a0.previews.dropboxusercontent.com/p/thumb/ABEy1DSpxsZQI8_1ZJrnTQ0Sxz6K4GVfKpeeAT3VgwsYdF3iM1I16J3k1dEBHcM4mW8_JjshtmTZVP05bZbtm3anqKB2bUK9TYMOk7DvW2bWO-SfZbaGhDfkJlmtbfuQvnp4WetRA2ptiCkOjtYuIfJHDrtKnjnHtGnSmgWQs_fH8z-An4dT94J6wt-RVK9wc9hSXcl-yEP1_GbY-2oMd0OfibSnbn1TKW27uAMQ8wPj-AMH7meBjznSr3jUPrn_WZW5GeFAkVi3UUUERAxmucOwloPHICKxBDg6v098GwxgvOE92cJGweOKMizxxUOdQBm1Wx8ehHMpb8Ps59DcuysqBlwDtJvdYktsxmzJ9XhPo7Bmu5RDkoIcWkpY8-HalYT29jBoIV2MhMNk8B86jVKy/p.png?fv_content=true&size_mode=5");
console.log(jimpSrc.bitmap.data)

Debugging

Debugging the js code:

Version

FYI, this bug is related with Stackoverflow question and the PNG 16bit grayscale comes from TUM and represents depth maps

remmel commented 3 years ago

This is not a fix, but I used fast-png lib which handle 16 grayscale:

import {decode} from 'fast-png'
[...]
var binDepth = await((await fetch(urlDepth)).arrayBuffer())
let depthPng = await decode(binDepth)
depthPng.data
Spiri0 commented 1 year ago

I have the same problem. Jimp is a very nice tool. You can see that there is a lot of ability and passion behind it. But it's a pity that after almost two years, despite several releases, this error has still not been fixed. That's why I use fast-png as well. The really big shortcoming of fast-png is that it doesn't work with workers. In the scientific field, 8 bits are not enough, 16 bits are very important. If jimp ran with workers and 16 bit, it would be the perfect choice for science

hipstersmoothie commented 1 year ago

If anyone here want to submit a PR I'm happy to review and merge!

hipstersmoothie commented 1 year ago

looking into pngjs3 https://github.com/gforge/pngjs3/issues/96