Bilddaten mit dem imageData-Objekt abrufen, verändern und speichern
Das JavaScript-Canvas-Objekt enthält mehrere Methoden, mit denen man Bildinhalte in ihrer Gesamtheit bearbeiten kann. Das sind
getImageData (startX, startY, breite, höhe)
- liest Bildinformationen aus der aktiven Zeichnungsfläche aus und speichert sie im ImageData-Objekt.putImageData (ImageData, startX, startY)
- schreibt die Bildinformationen des angegebenen ImageData-Objektes in die aktive ZeichnungsflächecreateImageData (breite, höhe)
- erstellt ein ImageData-Objekt
Ein einfaches Beispiel, bei dem zunächst eine Grafikdatei mit drawImage in die Canvas gezeichnet wird und dieses Bild mit getImageData
ausgelesen und dann wieder versetzt gezeichnet wird, könnte so aussehen:
function zeichne1(){ var myCanvas = document.getElementById('canvas_id'); if(myCanvas.getContext){ var cx = myCanvas.getContext('2d'); clean(cx); cx.save(); //Image-Objekt an den Koordinaten x=0;y=0 zeichnen cx.drawImage(objImg1, 0, 0); //komplettes Bild in imageData-Objekt laden var myImgData = cx.getImageData(0,0,objImg1.width,objImg1.height); //imageData-Objekt um 15 Pixel versetzt ausgeben cx.putImageData(myImgData, 15,15); cx.restore(); } }
Der Inhalt des ImageData-Objektes wird dabei nicht verändert.
Wenn man die Bildinformationen verändern will, muss man die Struktur des ImageData-Objektes kennen. Es enthält
ImageData.width
- die BreiteImageData.height
- die HöheImageData.data
- die Bildinformationen in einem Array
Das ImageData.data-Array enthält für jedes Pixel 4 Bytes:
- 1. Byte - Rotwert
- 2. Byte - Blauwert
- 3. Byte - Grünwert
- 4. Byte - Wert für Alpha-Transparenz
Die Länge eines ImageData.data-Array ergibt sich somit aus ImageData.width*ImageData.height*4. Man kann diese Information zur Länge auch mit ImageData.data.length
abfragen.
In dem folgenden Beispiel werden die Farbwerte so verändert, dass ein Schwarzweißbild entsteht und die Alpha-Transparenz wird auf 50% gesetzt.
var myCanvas = document.getElementById('canvas_id'); if(myCanvas.getContext){ var cx = myCanvas.getContext('2d'); clean(cx); cx.save(); //Image-Objekt an den Koordinaten x=0;y=0 zeichnen cx.drawImage(objImg1, 0, 0); //komplettes Bild in imageData-Objekt laden var myImgData = cx.getImageData(0,0,objImg1.width,objImg1.height); for (var x = 0; x < myImgData.width; x++) { for (var y = 0; y < myImgData.height; y++) { // Indexwert des imgDate-Objektes ermitteln var idx = (x + y * myImgData.width) * 4; // Ermittlung der RGB-Werte var r = myImgData.data[idx + 0]; var g = myImgData.data[idx + 1]; var b = myImgData.data[idx + 2]; // Farbewerte auf grau setzen, Alphatransparenz auf 50% var gray = (r + g + b) / 3; myImgData.data[idx + 0] = gray; myImgData.data[idx + 1] = gray; myImgData.data[idx + 2] = gray; myImgData.data[idx + 3] = 255*0.5; } } cx.putImageData(myImgData, 15,15); cx.restore(); }
Bei diesem Beispiel werden die Bilddaten in anderer Art und Weise modifiziert, so das ein interessanter Effekt entsteht.
Bei den bisherigen Beispielen wurde das ImageData-Objekt jeweils aus bereits bestehenden Bildinformationen generiert. Mit createImageData
kann man aber auch ein zunächst leeres Imagadata-Objekt erstellen, das dann nach belieben gefüllt wird um es abschließend auf die Canvas-Fläche zu projizieren. Das folgende Beispiel zeichnet nach dieser Vorgehensweise ein paar waagerechte Linien. Hier der Quellcode zu diesem Beispiel:
var myCanvas = document.getElementById('canvas_id'); if(myCanvas.getContext){ var cx = myCanvas.getContext('2d'); clean(cx); cx.save(); //Image-Objekt an den Koordinaten x=0;y=0 zeichnen cx.drawImage(objImg1, 0, 0); //komplettes Bild in imageData-Objekt laden var myImgData = cx.getImageData(0,0,objImg1.width,objImg1.height); for (var x = 0; x < myImgData.width; x++) { for (var y = 0; y < myImgData.height; y++) { // Indexwert des imgDate-Objektes ermitteln var idx = (x + y * myImgData.width) * 4; // Ermittlung der RGB-Werte var r = myImgData.data[idx + 0]; var g = myImgData.data[idx + 1]; var b = myImgData.data[idx + 2]; // Farbewerte auf grau setzen, Alphatransparenz auf 50% var gray = (r + g + b) / 3; myImgData.data[idx + 0] = gray; myImgData.data[idx + 1] = gray; myImgData.data[idx + 2] = gray; myImgData.data[idx + 3] = 255*0.5; } } cx.putImageData(myImgData, 15,15); cx.restore(); }