2014-05-06 11 views
11

Czy istnieje sposób na zatrzymanie wstępnego powiększenia kanału alfa dla danych obszaru roboczego lub rozwiązania zastępczego?Jak mogę zatrzymać wstępne powiększanie alfa przy użyciu obrazu na płótnie?

Chcę wygenerować obraz (w tym przypadku niektóre losowe wartości rgba) i zapisać płótno jako obraz.

Podczas drugiego kroku chcę porównać oryginalny obraz z wygenerowanym obrazem przy użyciu imageData, jednak to nie zadziała z powodu wstępnego powiększenia kanału alfa moich pikseli rgba w wygenerowanym obrazie.

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); 
} 

W konsoli znajdują się dwa wyjścia console.log. Pierwszy przed premipliplication, a drugi po premipliplication. Te dwa wyjścia są różne, niektóre wartości są wyłączone o 3 lub więcej. Dzieje się tak tylko w przypadku częściowej przezroczystości (alfa jest ustawione na coś innego niż 255).

Czy istnieje sposób na uzyskanie tego samego wyniku? Wszelkie pomysły na temat tego problemu? Wszelkich pomysłów, jak stworzyć coś w rodzaju obejścia tego problemu?

Z góry dziękuję!

+0

Jestem również zainteresowany odpowiedzią na to również.Dzieje się tak tylko wtedy, gdy alfa nie jest 255. – Loktar

+0

spójrz na specyfikację putImageData, w szczególności na końcu: http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element .html # dom-context-2d-putimagedata Jedynym rozwiązaniem, które widzę, jest użycie webGL do kontrolowania sposobu obsługi rgba. – GameAlchemist

Odpowiedz

13

Bleh, jest to uznany problem, jeśli chodzi o specyfikację obszaru roboczego. Zauważa:

Ze względu na charakter stratnej konwersji do i od wartości kolorów pikseli premultiplied alfa, które właśnie zostały określone przy użyciu putImageData() może być zwrócony do równoważnych getImageData() w różnych wartościach.

Więc tak:

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); 

wyjścia:

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

we wszystkich przeglądarkach.

Jest to operacja stratna, nie ma obejścia, chyba że zmieniono specyfikację w celu uzyskania opcji nieużywania premiksu. Zostało to omówione już w 2008 roku na liście dyskusyjnej WHATWG i zdecydowano, że "podróż w obie strony"/tożsamość danych obrazu typu "włóż/zbierz" nie jest obietnicą, której specyfikacja jest gotowa zażądać.

Jeśli zachodzi potrzeba "zapisania" danych obrazu, nie można go zapisać i zachować tę samą wierność przy użyciu metody putImageData. Obejścia polegające na narysowaniu pełnych danych alfa na tymczasowym płótnie i ponownym rysowaniu na płótnie głównym przy użyciu mniejszego globalAlpha również nie będą działać.

Więc nie masz szczęścia. Przepraszam.


W tym dniu (12 maja 2014) to nadal dostaje omówione na liście WHATWG: http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2014-May/296792.html

+0

Cieszę się, że twoja uwaga została do tego przyciągnięta. Wiedziałem, że jeśli ktokolwiek zdoła to rozgryźć, to byłbyś ty. – Loktar

+0

Link do lists.whatwg.org niestety umarł i nie mogę zlokalizować żadnych zarchiwizowanych kopii. Znalazłem to archiwum, ale bez tytułu wątku nie jestem pewien, o której wiadomości chodziło - https://lists.w3.org/Archives/Public/public-whatwg-archive/2014May/subject.html –

0

No to jeszcze wpadki ...

mam jeśli używasz to w tekstury dla webgl można po prostu przekazać jako jednolitą tablicę bajtową

Powiązane problemy