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äche
  • createImageData (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.

Beispiel ansehen

Wenn man die Bildinformationen verändern will, muss man die Struktur des ImageData-Objektes kennen. Es enthält

  • ImageData.width - die Breite
  • ImageData.height - die Höhe
  • ImageData.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();
}

Beispiel ansehen

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

Beispiel ansehen