java pixel data,从JavaScript中的图像读取pixeldata会为半透明像素返回意外的结果

I am reading RGBA data from a png file in JavaScript. To do this I draw the image on a canvas and use .getImageData. The data differs from what I expect:

The third pixel's RGBA in JS is: [9, 0, 0, 54] (tested in chrome and firefox) but it should be [12, 0, 0, 54] (at least it is what gimp and python pillow claim).

My guesses what could be wrong

drawImage does some compositing (setting ctx.globalCompositeOperation to copy does not make any difference)

there is some color mangament going on at load time of the image

Example Code

Select the test image

check console output

解决方案

1) Compositing

The more draw operations applied the more rounding errors will occur over time. However, with an initial draw this won't matter.

copy mode doesn't affect it as you discovered. This is just ignoring the existing background data. source-over do use alpha value of background, but as there is none initially it will have the same effect.

The main problem with this though is that there is general problems with alpha and rounding errors due to pre-multiplied alpha values which needs to be converted internally.

2) Color management

Browsers do support various levels of color management. This includes the following data from the PNG file:

sRGB chunk stating how the PNG conforms to the sRGB standard (relative, absolute etc.)

iCCP chunk which contains an ICC profile including gamma, that if the browser support ICC and also this version of ICC (typical versions are version 2 and 4).

If no sRGB or iCCP profile are found, it will look for gAMA chunk which contains a number representing the gamma.

When these data are applied it will alter the original bitmap. Gamma will not affect the lowest nor the highest values, but the mid-range will have a noticeable change. Values that are still altered will be altered due to color management and conversion errors (1.).

For example, even if the file does not have a gamma chunk (or a "file gamma"), which is the case for your test file, or its value is 1, a display gamma will still be applied (except in IE). For windows this would be 2.2 and for Mac typically 1.8.

And this happens before the image is returned to be used in the code with canvas.

Alternatively I would suggest taking a look at my

Test using pngtoy

This will show the raw unaltered bitmap value.

var out = document.querySelector("output"),

png = new PngToy();

png.fetch("https://i.imgur.com/oX1kom7.png").then(

function() {png.decode().then(show)}

);

function show(bmp) {

var data = bmp.bitmap;

out.innerHTML += data[8] + "," + data[9] + "," + data[10] + "," + data[11];

}

Loading external scripts (pngtoy.min.js + Promise polyfill for IE...)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值