2014-05-06 9 views
11

Gibt es eine Möglichkeit, die Vormultiplikation des Alphakanals für Canvas-Daten oder eine Umgehungsmöglichkeit zu stoppen?Wie kann ich die Alpha-Premultiplikation mit canvas imageData stoppen?

Ich möchte ein Bild (in diesem Fall einige zufällige rgba Werte) erstellen und die Leinwand als Bild speichern.

Während des zweiten Schritts möchte ich das Originalbild mit dem generierten Bild unter Verwendung der imageData vergleichen, jedoch wird dies aufgrund der Vormultiplikation des Alphakanals meiner rgba Pixel im generierten Bild nicht funktionieren.

The example

function drawImage(ctx) { 
    var img = ctx.createImageData(canvas.width,canvas.height); 

     for (var i=img.data.length;i-=4;) {  
       img.data[i] = Math.floor(Math.random() * 255); 
       img.data[i+1] = Math.floor(Math.random() * 255); 
       img.data[i+2] = Math.floor(Math.random() * 255); 
       img.data[i+3] = Math.floor(Math.random() * 255); 
     } 

     ctx.putImageData(img, 0, 0); 
      // our image data we just set 
     console.log(img.data); 
      // the image data we just placed onto the canvas 
     console.log(ctx.getImageData(0,0,canvas.width, canvas.height).data); 
} 

in der Konsole finden Sie zwei console.log Ausgänge finden. Das erste vor der Premultiplikation und das zweite nach der Premultiplikation. Diese beiden Ausgänge sind unterschiedlich, wobei einige Werte um 3 oder mehr abweichen. Dies ist nur dann der Fall, wenn teilweise Transparenz vorhanden ist (das Alpha wird auf einen anderen Wert als 255 gesetzt).

Gibt es eine Möglichkeit, dieselbe Ausgabe zu erhalten? Irgendwelche Ideen zu diesem Problem? Irgendwelche Ideen, wie man einen Workaround für dieses Problem erstellt?

Vielen Dank im Voraus!

+0

Ich bin an der Antwort darauf interessiert.Nur passiert, wenn das Alpha nicht 255 ist. – Loktar

+0

siehe die Spezifikation von putImageData, insbesondere die Endnote: http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element .html # dom-context-2d-putimagedata Die einzige Lösung, die ich sehe, ist die Verwendung von webGL, um zu steuern, wie rgba gehandhabt wird. – GameAlchemist

Antwort

13

Bleh, das ist ein anerkanntes Problem, soweit die Canvas-Spezifikation betroffen ist. Er stellt fest:

Aufgrund der verlustbehafteten Natur der Umwandlung zu und von premultiplied alpha-Farbwerte, Pixel, die gerade eingestellt wurden mit putImageData() könnte zu einer äquivalenten getImageData() als verschiedene Werte zurückgeführt werden.

So folgt aus:

var can = document.createElement('canvas'); 
var ctx = can.getContext('2d'); 
can.width = 1; 
can.height = 1; 
var img = ctx.createImageData(1, 1); 
img.data[0] = 40; 
img.data[1] = 90; 
img.data[2] = 200; 
var ALPHAVALUE = 5; 
img.data[3] = ALPHAVALUE; 
console.log(img.data); 
ctx.putImageData(img, 0, 0); 
console.log(ctx.getImageData(0, 0, 1, 1).data); 

Ausgänge:

[40, 90, 200, 5] 
[51, 102, 204, 5] 

In allen Browsern.

Das ist also eine verlustreiche Operation, es gibt keine Problemumgehung, es sei denn, sie ändern die Spezifikation, um eine Option zu geben, keine Premultiplikation zu verwenden. Dies wurde bereits 2008 in der WHATWG-Mailingliste diskutiert und sie entschieden, dass eine "Rundreise"/Identität von Put/Get-Bilddaten kein Versprechen ist, das die Spezifikation zu stellen bereit ist.

Wenn Sie die Bilddaten "speichern" müssen, können Sie sie nicht speichern und mit putImageData die gleiche Genauigkeit beibehalten. Problemumgehungen durch Zeichnen der Vollalpha-Daten auf eine temporäre Arbeitsfläche und Neuzeichnen auf die Hauptarbeitsfläche mit einer kleineren globalAlpha werden ebenfalls nicht funktionieren.

Sie haben also kein Glück. Es tut uns leid.


Bis zum heutigen Tag (12. Mai 2014) diese noch auf der WHATWG Liste diskutiert wird: http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2014-May/296792.html

+0

Froh, dass Ihre Aufmerksamkeit darauf gelenkt wurde. Ich wusste, wenn irgendjemand es herausfinden könnte, wären Sie es. – Loktar

+0

Der lists.whatwg.org-Link ist leider gestorben, und ich kann keine archivierten Kopien finden. Ich habe dieses Archiv gefunden, aber ohne einen Threadtitel bin ich nicht sicher, auf welche Nachricht Sie sich bezogen haben - https://lists.w3.org/Archives/Public/public-whatwg-archive/2014May/subject.html –

0

diese Nun ist noch ein Mist ...

ich denn wenn Sie mit es in einer Textur für Webgl Sie könnten es einfach als einheitliche Byte-Array übergeben

Verwandte Themen