CSS, HTML und Javascript mit {stil}

Canvas: Bitmaps analysieren und manipulieren

Bitmap img in Canvas laden und manipulieren Mario als Figur aus Pixeln

Javascript lädt Bilder in zwei Schritten in ein HTML-Canvas-Element:

  1. Das Bild wird als neues DOM-Element geladen,
  2. sobald das Bild geladen ist, kann es im Canvas gerendert werden.

Wenn die Canvas-Anwendung mit Bildern arbeitet, werden die Bilder am besten vor dem Rendern des Bildes geladen.

Script zum Aufhellen und Abdunkeln von RGB-Werten von Stackoverflow

<canvas id="mycan" width="300" height="299"></canvas>
… 
var canvas = document.getElementById('mycan');
var ctx = canvas.getContext('2d');
var image = new Image();               // Bild laden
image.src = "obst.png";
$(image).load(function() {             // Wenn das Bild geladen ist
    ctx.drawImage (image, 0, 0);       // Bild in Canvas laden
});

(»$-Zeichen« $(image): Mit Hilfe von jQuery)

ctx.drawImage (image, 0, 0): Das zweite und dritte Argument von drawImage sind die Start-Koordinaten des Bildes – also die Position der linken oberen Ecke.

Bilder im Canvas scale und clip

Mit zwei weiteren Argumenten bestimmt der Canvas Breite und Höhe des Bildes, um das Original zu vergrößern oder zu verkleinern.

Die nächsten beiden Argumente verschieben den Ausschnitt im Canvas.

Einen vergrößerten oder verkleinerten Ausschnitt des Bildes zeigt HTML Canvas mit insgesamt 8 Argumenten:

sx, sy
Linke obere Ecke des Bildausschnitts
sw, sh
Breite und Höhe des Ausschnitts aus dem Originalbild
dx, dy
Linke obere Ecke des Bildausschnitts im Canvas
dw, dh
Breite und Höhe des Ausschnitts im Canvas
// ctx.drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh)

$('#gr').click(function () {
	ctx.clearRect ( 0 , 0 , canvasWidth , canvasHeight );
	ctx.drawImage(image,100,100,50,50,5,5,250,250 )
});
$('#kl').click(function () {
	ctx.clearRect ( 0 , 0 , canvasWidth , canvasHeight );
	ctx.drawImage(image,0,0,300,299,30,30,100,100 );
});
$('#reset').click(function () {
	ctx.clearRect ( 0 , 0 , canvasWidth , canvasHeight );
	ctx.drawImage(image,0,0,canvasWidth, canvasHeight);
});

Verkleinern und Vergrößern arbeitet ohne Weiteres auf den Pixeln des Originalbildes, auch wenn die Pixel durch das Script verändert wurden.

Werden die Pixel geändert, reicht ein einfaches Reset des Canvas nicht aus: Um wieder an die Pixel des Originalbildes zu kommen, müssen die Pixel am Anfang des Scripts in einem Puffer gespeichert werden und beim Reset muss der Puffer die Original-Pixel wieder herstellen. Das einfache Reset wie im Codebeispiel reicht nicht aus.

Javascript Canvas Sicherheit

Aus Sicherheitsgründen darf Javascript nur Bilder innerhalb der selben Domaine / desselben Verzeichnisses manipulieren. Die Pixel eines Bildes auf einem Remote Server können also nicht analysiert und manipuliert werden (eigentlich schade … ).

IE analysiert und manipuliert sogar nur Bilder innerhalb einer Server-Umgebung, nicht aber im lokalen Verzeichnis des Rechners.

Javascript Zugriff auf Canvas-Pixel

Um die Pixel eines Bildes zu manipulieren – z.B. aufzuhellen oder zu invertieren – müssen die Pixel linearisiert werden. Aus ist es mit der schönen Pixelmatrix eines Bildes: Wir erreichen einen Pixel nicht über »gibt mir Pixel 10 in Reihe 3«. Alle Pixel liegen in einem einfachen eindimensionalen Array.

var imageData = ctx.getImageData(0, 0, canvasWidth, canvasHeight);
var data = imageData.data;

gibt ein CanvasPixelArray mit den Farbwerten der Pixel des Bildausschnitts zurück.

Das heißt aber immer noch nicht, dass der Pixel 10 in Reihe 3 jetzt auf dem Index 3*10 - 1 liegt, sondern nur, dass der Pixel auf dieser Position beginnt.

RGB und Alpha: Take 4

Javascript Canvas stellt alle Pixel des Bildes durch vier Werte dar: Rot, Grün, Blau und Alpha.

Wenn schon ein Winzling mit 3x3 Pixeln mit 36 Helligkeitswerten dasteht – die Manipulation von Pixelbildern ist zeitintensiv.

Der Index des ersten Pixels ist 0, der Index des zweiten Pixels ist 4, der Index des dritten Pixels ist 12, …. Jedes Pixel beginnt also auf einem Vielfachen von 4.

Der mittlere Pixel einer 3x3 Matrix beginnt auf Index 16 und enthält die RGB-Werte auf 16+1 (Grün), 16+2 (Blau), 16+3 (Alpha)

var red = ((y-1) * (width * 4)) + ((x - 1) * 4);
var blue = ((y-1) * (width * 4)) + ((x - 1) * 4) + 1;
var green = ((y-1) * (width * 4)) + ((x - 1) * 4) + 2;
var alpha = ((y-1) * (width * 4)) + ((x - 1) * 4) + 3;
$('#alpha').click(function () {
for (var x=0; x<numPixels; x++) {
   if (parseInt(pixels[x*4+3]) == 0 ) {
      pixels[x*4] = 0;
      pixels[x*4+1] = 0;
      pixels[x*4+2] = 0;
      pixels[x*4+3] = 255;
	}
}
ctx.clearRect ( 0 , 0 , canvasWidth , canvasHeight );
ctx.putImageData(imageData, 0, 0);
CANVAS PIXEL 0 4 8 12 16 20 24 28 32 0 4 8 12 16 20 24 28 32 0 1 2 3rgba 4 5 6 7rgba 8 9 10 11rgba