2016-05-01 15 views
0

Ich lade ein Bild in eine Leinwand; Ich zeichneImage(), speichern Sie getImageData() in eine Variable zum Manipulieren. Ich würde gerne in der Lage sein, die Daten zum Beispiel mehrmals zu manipulieren: verschiedene Filter hinzufügen/entfernen. Wie kann ich die Daten so speichern, dass sie jedes Mal aktualisiert werden, wenn ich das Bild mit putImageData() zeichne?Leinwand/Foto - getImageData funktioniert nicht

Grundsätzlich denke ich, dass ich die Verwendung von getImageData falsch verstehe oder falsch verwende. Mein Gedanke war, dass jede Manipulation, die mit dem Bild gemacht wurde, getImageData ausführen und die Variable, die die Information enthielt, aktualisieren und damit das Bild neu zeichnen konnte.

Beispiel: In den Ausschnitt unten Lets sagen, dass ich eine Funktion ausführen, die das Bild schwarz und weiß drehen. Ich habe eine andere Funktion, die die Größe des Bildes ändert, wenn es angeklickt wird. Wenn ich das Bild verkleinere, verschwindet der Schwarz-Weiß-Filter. Was mache ich falsch, um die Informationen des Bildes zu behalten?

//Read in picture 
var reader = new FileReader(); 
       reader.onload = function leDraw(e){ 
        imgObj = new Image(); 
        picWidth = canvas.width/2; 
        picHeight = canvas.height/2; 
        imgObj.src = e.target.result; 
        newX = 0; 
        newY = 0; 
        ctx.drawImage(imgObj,0,0, picWidth, picHeight); 
        imageData = ctx.getImageData(newX,newY, canvas.width, canvas.height); 
        originalCopy = ctx.getImageData(newX,newY, picWidth, picHeight); 
        data = imageData.data; 

function resize(val){ Resizes picture 

     userPicHeight = document.getElementById("cSelect").value; 
     userPicWidth = document.getElementById("cSelect").value; 
     ctx.clearRect(0,0, canvas.width, canvas.height); 
     ctx.drawImage(imgObj, newX, newY, userPicWidth, userPicHeight); 
     window['imageData'] = ctx.getImageData(newX,newY, userPicWidth, userPicHeight); 
     ctx.putImageData(imageData, newX, newY); 
    }; 

Antwort

1

imageData ist eine Momentaufnahme von Canvas-Pixeldaten. In Ihrem Fall sind es die gesamten Pixeldaten der gesamten Leinwand (farbig - nicht B & W).

Also, wenn Sie .putImageData(imageData...) tun, wird die unveränderte Snapshow wieder auf der Leinwand angezeigt.

Wenn Sie ein B & W Version des Bildes neu zu skalieren wollen:

  1. Zeichnen Sie Ihre Farbbild auf einer neuen Leinwand mit var memCanvas = document.createElement erstellt. Größe der Leinwand auf die Bildgröße. Der Canvas kann im Speicher bleiben - nicht appendChild es in das DOM.

  2. Den Filter auf die neue Zeichenfläche mit getImageData anwenden, Pixeldaten ändern, putImageData. Jetzt haben Sie ein "Bild-Canvas", das Sie später verwenden können, um die Größe zu ändern usw.

  3. Zeichnen Sie das Bild-Canvas auf die sichtbare Leinwand: context.drawImage(memCanvas,0,0). Ja, memCanvas kann eine Bildquelle für drawImage sein.

  4. die B & W Version des Bildes skalieren, nur die Leinwand löschen, skalieren die Leinwand mit context.scale & dann mit drawImage(memCanvas,0,0)

des skalierten B & W Bild zeichnen Wenn Sie später erneut wollen - Skalieren Sie das Bild B & W, Sie können Schritt 4 erneut ausführen.

Beispielcode und ein Demo ein Graufilter:

var canvas=document.getElementById("canvas"); 
 
var ctx=canvas.getContext("2d"); 
 
var cw=canvas.width; 
 
var ch=canvas.height; 
 

 
var img=new Image 
 
img.crossOrigin='anonymous'; 
 
img.onload=start; 
 
img.src="https://dl.dropboxusercontent.com/u/139992952/multple/kingcard.png"; 
 
function start(){ 
 

 
    // create a grayscale image-canvas 
 
    var grayImg=makeFilteredImageCanvas(img,grayscaleFilter); 
 
    
 
    // scale the visible canvas 
 
    ctx.scale(1.25,1.25); 
 
    
 
    // draw the grayscale imag-canvas on the canvas 
 
    // (the result will be scaled) 
 
    ctx.drawImage(grayImg,0,0); 
 

 
} 
 

 
function makeFilteredImageCanvas(img,filter){ 
 
    var c=document.createElement('canvas'); 
 
    var cctx=c.getContext('2d'); 
 
    iw=c.width=img.width; 
 
    ih=c.height=img.height; 
 
    cctx.drawImage(img,0,0); 
 
    filter(cctx); 
 
    return(c); 
 
} 
 

 
function grayscaleFilter(context){ 
 
    var canvas=context.canvas; 
 
    var w=canvas.width; 
 
    var h=canvas.height; 
 
    var imageData=context.getImageData(0,0,w,h); 
 
    var data=imageData.data; 
 
    for(var i=0;i<data.length;i+=4){ 
 
      var gray=data[i]*0.33+data[i+1]*0.5+data[i+2]*0.16; 
 
      data[i]=data[i+1]=data[i+2]=gray; 
 
    } 
 
    context.putImageData(imageData,0,0); 
 
}
body{ background-color: ivory; } 
 
#canvas{border:1px solid red; margin:0 auto; }
<h4>Grayscale image scaled up by 25%</h4> 
 
<canvas id="canvas" width=300 height=300></canvas> 
 
<h4>Original Image:</h4> 
 
<img src='https://dl.dropboxusercontent.com/u/139992952/multple/kingcard.png' crossOrigin='anonymous'>

+1

Danke, löscht dies einige Dinge für mich und gibt mir ein paar Ideen zu arbeiten. Die eine kleine Sache, die ein Problem für mich bleibt, ist die tatsächliche "Skalierung" in meinem Projekt basiert auf der Benutzereingabe von einem Schieberegler. Darüber hinaus ist das Projekt wie ein Foto-Editor, so dass der Benutzer klicken und ziehen kann, um das Foto zu verschieben, ändern und mehrere Filter hinzufügen.Dieses Beispiel gibt mir definitiv einige Ideen. – swam

+0

Gern geschehen. Ja, ein im Cache gefiltertes Bild-Canvas macht die Größenänderung sehr viel effizienter, da Sie nicht jedes Mal neu filtern müssen. – markE

Verwandte Themen