New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Encode 16bit image #17
Comments
Nobody needed 16-bit encoding yet, but I think it should be quite easy to do :) What is your use case? |
hi, thanks for your reply. I use it to display scientific image from
microscopies, they are single channel 16-bit tiff or png format, I need to
load them into canvas, apply look up table to display, or process them and
encode into png files.
It’s important for me to support 16bit grayscale, ideally, also support
multi frame apng encoding.
EDIT: in my case, I use Uint16Array typed arrays to store image data, I need a lossless way to store my data. I feel like this png is a better solution, more portable than tiff format, since you also said "You should not save images into TIFF format in the 21st century. Save them as PNG instead".
…On Thu, Mar 1, 2018 at 6:27 PM Photopea ***@***.***> wrote:
Nobody needed 16-bit encoding yet, but I think it should be quite easy to
do :) What is your use case?
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#17 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAdNy6wdBk32x-PtNNji85mlZrn3A7O6ks5taCyVgaJpZM4SYq5u>
.
|
Saving 16-bit PNGs is not that hard, but we need a nice interface for it. The current UPNG.encode() expects 8-bit RGBA image. I could let it accept 16-bit RGBA images (iff the input ArrayBuffer is 2x bigger than it should be). Would you mind reconverting your grayscale into RGBA before encoding? (i.e. R=G=B=Gray, Alpha=0xffff , the image would become 4x larger) ? It would require you to reconvert your grayscale and use 4x more memory, but it would let us keep using the single UPNG.encode() function. Otherwise, we would need new functions UPNG.encodeGray8(), UPNG.encodeGray16() .... or more complicated parameters. BTW. don't worry about your output PNGs being too large. UPNG would detect the "grayness" of RGBA and encode it appropriatelly. |
Thanks for your response. Can we just use UPNG.encode but detect the
channel of the input image instead? Or we add a bit mode parameter?
…On Sun 1 Apr 2018 at 18:10, Photopea ***@***.***> wrote:
Saving 16-bit PNGs is not that hard, but we need a nice interface for it.
The current UPNG.encode() expects 8-bit RGBA image. I could let it accept
16-bit RGBA images (iff the input ArrayBuffer is 2x bigger than it should
be). Would you mind reconverting your grayscale into RGBA before encoding?
(i.e. R=G=B=Gray, Alpha=0xffff , the image would become 4x larger) ?
It would require you to reconvert your grayscale and use 4x more memory,
but it would let us keep using the single UPNG.encode() function.
Otherwise, we would need new functions UPNG.encodeGray8(),
UPNG.encodeGray16() .... or more complicated parameters.
BTW. don't worry about your output PNGs being too large. UPNG would detect
the "grayness" of RGBA and encode it appropriatelly.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#17 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAdNy2MWQlRLv2qDr1DelzpTUpyp4LmTks5tkPwOgaJpZM4SYq5u>
.
|
The UPNG.encode gets Width, Height, and array of bytes of specific length. If we know, that the input is RGBA (four channels), we can deduce the channel depth from the area (width x height) and array length. Do you understand what I mean by "unwrapping" your grayscale into RGBA? Are your images too large to do it? How large are they? |
I think that would be a big constrain, since we have image size up to
25600x25600, can be bigger in extreme cases. Now I try to limit to
2560x2560.
…On Sun 1 Apr 2018 at 19:04, Photopea ***@***.***> wrote:
The UPNG.encode gets Width, Height, and array of bytes of specific length.
If we know, that the input is RGBA (four channels), we can deduce the
channel depth from the area (width x height) and array length.
Do you understand what I mean by "unwrapping" your grayscale into RGBA?
Are your images too large to do it? How large are they?
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#17 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAdNy2hQ1xB-50zxvFLU-wHFbzWQmdZZks5tkQiLgaJpZM4SYq5u>
.
|
Wow, the 25600x25600 image would have 1.3 GB uncompressed (2 bytes per pixel). How large are these TIFFs? Do they have a lossy or lossless compression? If they are lossy, maybe you should use JPG instead of PNG. |
We don’t have a good format to save the whole image right now, I have to
crop it and save it as png. We use lossless compression, sometimes no
compression.
…On Sun 1 Apr 2018 at 19:30, Photopea ***@***.***> wrote:
Wow, the 25600x25600 image would have 1.3 GB uncompressed (2 bytes per
pixel). How large are these TIFFs? Do they have a lossy or lossless
compression? If they are lossy, maybe you should use JPG instead of PNG.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#17 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAdNy05-X45l7YuLeXWdlPFFgsVfUno4ks5tkQ6rgaJpZM4SYq5u>
.
|
UPNG.js supports "lossy compression" - quantization by a palette of colors (e.g. just 20 colors for the whole image). But these methods expect 8-bit colors right now. BTW. why don't you reconvert your images to 8-bits? It would be a form of "lossy compression" and then you can give it to UPNG.js |
That’s what I could do right now, but these images are sometimes used in a
“photon count” mode, we will need 16-bit(sometimes 24-bit) to record the
photon number in each pixel.
I am also wondering can we just use RGBA 4 channel to represent a 32-bit
grayscale image, but that would means the image will look wired with a
standard png image reader.
Anyway, I would suggest to support 16bit grayscale image encoding without a
big memory overhead. Hopefully with APNG mode, so we can save many frames
in one file.
…On Sun 1 Apr 2018 at 21:09, Photopea ***@***.***> wrote:
UPNG.js supports "lossy compression" - quantization by a palette of colors
(e.g. just 20 colors for the whole image). But these methods expect 8-bit
colors right now.
BTW. why don't you reconvert your images to 8-bits? It would be a form of
"lossy compression" and then you can give it to UPNG.js
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#17 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAdNy18cJrJ6u5sxFcp63_xMQgtLCXBVks5tkSXwgaJpZM4SYq5u>
.
|
I think I can expose a low-level encode function for you (that lets you specify the number of channels and bits per channel). PNG format does not support 32-bit color depth now (but I guess most of image viewers can not display 32-bit TIFF either). Sure, you could split bits into multiple channels, but image viewers would not display it as intended. But do you really need "regular people" to be able to display it? If you want to show it on your website, I would convert it to a smaller bit depth and resolution, so visitors don't have to wait for hours until it is loaded. |
That sounds great to me, thanks.
You are right, I don’t need regular user to see it anyway.
…On Mon 2 Apr 2018 at 09:47, Photopea ***@***.***> wrote:
I think I can expose a low-level encode function for you (that lets you
specify the number of channels and bits per channel).
PNG format does not support 32-bit color depth now (but I guess most of
image viewers can not display 32-bit TIFF either). Sure, you could split
bits into multiple channels, but image viewers would not display it as
intended. But do you really need "regular people" to be able to display it?
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#17 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAdNy2IQCAOq52YI861dPEGjE9m6db-lks5tkdePgaJpZM4SYq5u>
.
|
Have you tried to "tunnel" your 16-bit grayscale as 8-bit RGBA? Pass your ArrayBuffer to UPNG.encode() and set the height to a half (so the number of bytes corresponds). Later, after you decode it, multiply the height by 2 and read ArrayBuffer as Uint16Array. It should work. E.g. Your 3x4 16-bit image has 12x2=24 bytes. Look at those bytes as the 3x2 8-bit RGBA image (6 pixels x 4 bytes per pixel = 24 bytes). |
No, I haven’t, I agree that it should work.
Forgot to mention, another thing stop me from doing that is we want the
file can be opened with scientific image processing software such as imagej
(https://imagej.nih.gov/ij/). People don’t want save files which can only
read from one single app.
…On Mon 2 Apr 2018 at 11:33, Photopea ***@***.***> wrote:
Have you tried to "tunnel" your 16-bit grayscale as 8-bit RGBA? Pass your
ArrayBuffer to UPNG.encode() and set the height to a half (so the number of
bytes corresponds). Later, after you decode it, multiply the height by 2
and read ArrayBuffer as Uint16Array. It should work.
E.g. Your 3x4 16-bit image has 12x2=24 bytes. Look at those bytes as the
3x2 8-bit RGBA image (6 pixels x 4 bytes per pixel = 24 bytes).
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#17 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAdNyz3V_I1l1e_VlMCzxYrdGLPNwpYHks5tkfBbgaJpZM4SYq5u>
.
|
Hi, so I implemented the support for 16-bit images. Have a look at UPNG.encodeLL() |
Great, thanks, I will have a try and let you know. |
Do you mean for decoding? it can be read directly from img.data |
I think the problem is in Endianity. Uint16Array in JS is usually little-endian (I hope they will fix the endianity in the spec soon). While PNG integers are big-endian - https://www.w3.org/TR/2003/REC-PNG-20031110/#3networkByteOrder . Such problem was never noticed in UPNG.js, because endianity does not matter for pixel depths <= 8 :) So you have to reorder two bytes within your Uint16 value. |
Hi, you are right. It's the Endianity issue. function swap16(val) {
return ((val & 0xFF) << 8) | ((val >> 8) & 0xFF);
} Thanks very much. |
ok i am glad it works :) |
could you please post the code on how the swap16 function need to be called |
Hi,
Thanks for the nice png library. It's great that it support 16bit image decoding, will 16-bit encoding be supported? Thank you.
The text was updated successfully, but these errors were encountered: