2015-08-22 9 views

Antwort

6

Diese Schwärzung tritt auf, weil die Umwandlung von 'image/jpeg' das Alpha aller Canvas-Pixel vollständig undurchsichtig macht (Alpha = 255). Das Problem ist, dass transparente Canvas-Pixel fully-black-but-transparent sind. Wenn Sie also diese schwarzen Pixel undurchsichtig machen, ist das Ergebnis ein geschwärztes JPEG.

Die Problemumgehung besteht darin, alle undurchsichtigen Canvas-Pixel manuell in die gewünschte weiße Farbe anstelle von Schwarz zu ändern.

Auf diese Weise, wenn sie gemacht werden undurchsichtig sie weiß statt schwarz Pixel angezeigt.

Hier ist, wie:

// change non-opaque pixels to white 
var imgData=ctx.getImageData(0,0,canvas.width,canvas.height); 
var data=imgData.data; 
for(var i=0;i<data.length;i+=4){ 
    if(data[i+3]<255){ 
     data[i]=255; 
     data[i+1]=255; 
     data[i+2]=255; 
     data[i+3]=255; 
    } 
} 
ctx.putImageData(imgData,0,0); 
+0

Vielen Dank. Kann ich dies in ASP.NET-Code hinterher tun, nachdem das schwarz gefüllte Bild an den Code hinterher übergeben wurde? –

+0

Gern geschehen! Sie sollten das Image auf der Client-Seite bearbeiten, bevor Sie es an Code-Behind übergeben. Das liegt daran, dass html5 canvas nur mit JavaScript funktioniert und JS in code-behind nicht nativ verfügbar ist (zumindest nicht in den für die Verwendung von html5 canvas notwendigen Möglichkeiten). – markE

+0

Ich kann nicht glauben, dass dies der einzige Weg ist, dies anzugehen. Es muss eine Möglichkeit geben, die Standardfarbe zu ändern. Ich werde das recherchieren müssen. – Laereom

2

Marks Antwort richtig ist, aber wenn ein Bild einer gewissen Anti-Aliasing angewandt hat, wird das exportierte Bild nicht so gut sein, wie es (vor allem Text) sein sollte. Ich mag seine Lösung verbessern:

// change non-opaque pixels to white 
var imgData=ctx.getImageData(0,0,canvas.width,canvas.height); 
var data=imgData.data; 
for(var i=0;i<data.length;i+=4){ 
    if(data[i+3]<255){ 
     data[i] = 255 - data[i]; 
     data[i+1] = 255 - data[i+1]; 
     data[i+2] = 255 - data[i+2]; 
     data[i+3] = 255 - data[i+3]; 
    } 
} 
ctx.putImageData(imgData,0,0); 
0
// change non-opaque pixels to white 
var imgData=ctx.getImageData(0,0,canvas.width,canvas.height); 
var data=imgData.data; 
for(var i=0;i<data.length;i+=4){ 
    if(data[i+3]<255){ 
     data[i] = 255 - data[i]; 
     data[i+1] = 255 - data[i+1]; 
     data[i+2] = 255 - data[i+2]; 
     data[i+3] = 255 - data[i+3]; 
    } 
+0

Ich schlage vor, Sie fügen eine Erklärung hinzu, wie dies das Problem behebt – Obromios

0

Wenn Sie nur vollen weißen transparenten Pixel verschieben wollen nur überprüfen (data [i + 3] == 0) anstelle von (Daten [i + 3] < 255).

5

Diese Antwort ist ein bisschen länger, aber ich finde es "korrekter", dass es diese Dinge behandelt, ohne direkt Rohdaten zu modifizieren. Ich finde das eine ziemlich chaotische und theoretisch unbefriedigende Lösung. Es gibt eingebaute Funktionen, um das zu erreichen, und sie sollten benutzt werden. Hier ist die Lösung, die ich gefunden/pilfered:

function canvasToImage(backgroundColor){ 

var context = document.getElementById('canvas').getContext('2d'); 

canvas = context.canvas; 
//cache height and width   
var w = canvas.width; 
var h = canvas.height; 

var data; 

//get the current ImageData for the canvas. 
data = context.getImageData(0, 0, w, h); 

//store the current globalCompositeOperation 
var compositeOperation = context.globalCompositeOperation; 

//set to draw behind current content 
context.globalCompositeOperation = "destination-over"; 

//set background color 
context.fillStyle = backgroundColor; 

//draw background/rect on entire canvas 
context.fillRect(0,0,w,h); 

//get the image data from the canvas 
var imageData = this.canvas.toDataURL("image/jpeg"); 

//clear the canvas 
context.clearRect (0,0,w,h); 

//restore it with original/cached ImageData 
context.putImageData(data, 0,0); 

//reset the globalCompositeOperation to what it was 
context.globalCompositeOperation = compositeOperation; 

//return the Base64 encoded data url string 
return imageData; 
} 

Grundsätzlich Sie ein weißes Hintergrundbild erstellen und Unterlage unter der Leinwand und dann das drucken. Diese Funktion wird meistens von jemandes Blog kopiert, aber es erforderte ein wenig Modifikation - wie zum Beispiel den Kontext zu bekommen - und direkt von meinem (Arbeits) Code kopiert, so lange wie das Element canvas die ID 'canvas' hat, Sie sollten in der Lage sein, es zu kopieren und einfügen und es funktioniert.

Dies ist der Blog-Post ich es von geändert:

http://www.mikechambers.com/blog/2011/01/31/setting-the-background-color-when-generating-images-from-canvas-todataurl/

Der große Vorteil meiner Funktion über diese ist, dass es gibt statt png JPEG, die auch in Chrom arbeiten wahrscheinlicher mit einem Dataurlimit von 2MB, und es ergreift tatsächlich den Kontext, was eine eklatante Auslassung in der ursprünglichen Funktion war.