2016-03-16 49 views
2

請看下面的例子:http://codepen.io/anon/pen/QNGzBPHTML帆布不精確設置像素顏色當α低於一個

const canvas = document.getElementById('canvas') 
const ctx = canvas.getContext('2d') 

// set pixel at 0,0 to rgba(2, 0, 255, 0.2) 
const imageData = ctx.getImageData(0, 0, 1, 1) 
imageData.data[0] = 2 
imageData.data[1] = 0 
imageData.data[2] = 255 
imageData.data[3] = 0.2 * 255 // 0.2 opacity 
ctx.putImageData(imageData, 0, 0, 0, 0, 1, 1) 
console.log('Setting pixel 0,0 to', { 
    r: imageData.data[0], 
    g: imageData.data[1], 
    b: imageData.data[2], 
    a: imageData.data[3]/255 
}) 

// retrieve pixel at 0,0 
const newImageData = ctx.getImageData(0, 0, 1, 1) 
console.log('Fetching pixel at 0,0', { 
    r: newImageData.data[0], 
    g: newImageData.data[1], 
    b: newImageData.data[2], 
    a: newImageData.data[3]/255 
}) 

上面的代碼修改在畫布上的單個像素,然後檢索它,而控制檯登錄的處理。當alpha低於1時,畫布似乎會突變RGB數據。

這似乎在Chrome和Firefox中都會出現。這只是一個瀏覽器錯誤?我從畫布中生成PNG,並要求顏色100%準確。有什麼解決方法嗎?

編輯:

http://codepen.io/anon/pen/ZWLbKx

更多的測試表明阿爾法如何變異的RGB值。

+2

畫布imageData的alpha元素是0-255範圍內的整數。非整數無效(它們可能被裝箱或忽略)。 – markE

+0

是的,但它仍然會改變數值,即使當您將'a'設置爲'51'時,至少對我來說.'ctx.fillStyle =「rgba(」+ r +「,」+ g +「,」+ b +「, +(A/255)+ 「)」; ctx.fillRect(x,y,1,1);'按預期工作,並且能夠在稍後成功返回值 – Wish

+0

我做了第二個測試,更好地顯示了rgb由alpha變異。 –

回答

0

非常抱歉令人失望,但HTML5畫布已被批准爲「有損」:它使用alpha通道預乘。

https://www.w3.org/TR/2dcontext/#dom-context-2d-getimagedata(見第二屆「注:」框):

由於轉換和預乘alpha的有損自然的顏色值,剛纔已經使用putImageData()設置的像素可能會被返回到等同於getImageData()作爲不同的值。

...有很多JavaScript PNG編碼器/解碼器。不幸的是,這是在2017年。

FWIW,我已經去碰撞r/g/b/a值上下,試圖讓畫布吐出我真正想要的值。 5分鐘的實驗表明,它會根據alpha的設置,「跳」到特定的像素值。