231 Stimmen

Wie kann ich am besten ein einzelnes Pixel in einem HTML5-Canvas setzen?

Der HTML5-Canvas hat keine Methode zum expliziten Setzen eines einzelnen Pixels.

Es könnte möglich sein, ein Pixel mit einer sehr kurzen Zeile zu setzen, aber dann könnten Antialisierung und Zeilenbegrenzung stören.

Eine andere Möglichkeit wäre die Erstellung eines kleinen ImageData Objekt und verwenden:

context.putImageData(data, x, y)

um sie einzurichten.

Kann jemand einen effizienten und zuverlässigen Weg beschreiben, dies zu tun?

4voto

sdleihssirhc Punkte 41111

Wie wäre es mit einem Rechteck? Das muss effizienter sein als die Erstellung eines ImageData Objekt.

4voto

erik Punkte 3900

Zeichne ein Rechteck, wie sdleihssirhc sagte!

ctx.fillRect (10, 10, 1, 1);

^-- soll ein 1x1-Rechteck bei x:10, y:10 zeichnen

2voto

Ich verwende diese einfache Funktion ausschließlich zu Diagnosezwecken.

Hinweis: Wenn keine ganzzahligen Koordinaten verwendet werden, ist das Bild unscharf.

setPixel (context, 100, 100, 'blue');

function setPixel (ctx, x, y, c) {

//  integer coordinates are required.

    ctx.save ();
    ctx.fillStyle = c;
    ctx.fillRect (x, y, 1, 1);
    ctx.restore ();

}

1voto

trusktr Punkte 39258

Hmm, du könntest auch einfach eine 1 Pixel breite Linie mit einer Länge von 1 Pixel machen und ihre Richtung entlang einer einzigen Achse bewegen lassen.

            ctx.beginPath();
            ctx.lineWidth = 1; // one pixel wide
            ctx.strokeStyle = rgba(...);
            ctx.moveTo(50,25); // positioned at 50,25
            ctx.lineTo(51,25); // one pixel long
            ctx.stroke();

1voto

Schneller HTML-Demo-Code: Basierend auf dem, was ich über die C++-Grafikbibliothek SFML weiß:

Speichern Sie diese als HTML-Datei mit UTF-8-Kodierung und führen Sie sie aus. Fühlen Sie sich frei zu überarbeiten, ich mag einfach japanische Variablen verwenden, weil sie prägnant sind und nicht viel Platz wegnehmen

In den seltensten Fällen werden Sie EIN beliebiges Pixel setzen und anzeigen wollen auf dem Bildschirm anzeigen. Verwenden Sie daher die

PutPix(x,y, r,g,b,a) 

Methode, um zahlreiche beliebige Pixel in einen Backbuffer zu zeichnen. (billige Aufrufe)

Wenn Sie bereit sind zu zeigen, rufen Sie die

Apply() 

Methode, um die Änderungen anzuzeigen. (teurer Aufruf)

Vollständiger Code der HTML-Datei unten:

<!DOCTYPE HTML >
<html lang="en">
<head>
    <title> back-buffer demo </title>
</head>
<body>

</body>

<script>
//Main function to execute once 
//all script is loaded:
function main(){

    //Create a canvas:
    var canvas;
    canvas = attachCanvasToDom();

    //Do the pixel setting test:
    var test_type = FAST_TEST;
    backBufferTest(canvas, test_type);
}

//Constants:
var SLOW_TEST = 1;
var FAST_TEST = 2;

function attachCanvasToDom(){
    //Canvas Creation:
    //cccccccccccccccccccccccccccccccccccccccccc//
    //Create Canvas and append to body:
    var can = document.createElement('canvas');
    document.body.appendChild(can);

    //Make canvas non-zero in size, 
    //so we can see it:
    can.width = 800;
    can.height= 600;

    //Get the context, fill canvas to get visual:
    var ctx = can.getContext("2d");
    ctx.fillStyle = "rgba(0, 0, 200, 0.5)";
    ctx.fillRect(0,0,can.width-1, can.height-1);
    //cccccccccccccccccccccccccccccccccccccccccc//

    //Return the canvas that was created:
    return can;
}

//THIS OBJECT IS SLOOOOOWW!
//  == "pen"
//T == "Type:Pen"
function T(canvas){

    //Publicly Exposed Functions
    //PEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPE//
    this.PutPix = _putPix;
    //PEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPE//

    if(!canvas){
        throw("[NilCanvasGivenToPenConstruct]");
    }

    var _ctx = canvas.getContext("2d");

    //Pixel Setting Test:
    // only do this once per page
    //  =="image"
    //  =="data"
    //=="image data"
    //  =="pen"
    var _ = _ctx.createImageData(1,1); 
    // only do this once per page
    var _  = _.data;   

    function _putPix(x,y,  r,g,b,a){
        _[0]   = r;
        _[1]   = g;
        _[2]   = b;
        _[3]   = a;
        _ctx.putImageData( _, x, y );  
    }
}

//Back-buffer object, for fast pixel setting:
// =="butt,rear" using to mean "back-buffer"
//T=="type: back-buffer"
function T(canvas){

    //Publicly Exposed Functions
    //PEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPE//
    this.PutPix = _putPix;
    this.Apply  = _apply;
    //PEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPE//

    if(!canvas){
        throw("[NilCanvasGivenToPenConstruct]");
    }

    var _can = canvas;
    var _ctx = canvas.getContext("2d");

    //Pixel Setting Test:
    // only do this once per page
    //  =="image"
    //  =="data"
    //=="image data"
    //  =="pen"
    var _w = _can.width;
    var _h = _can.height;
    var _ = _ctx.createImageData(_w,_h); 
    // only do this once per page
    var _  = _.data;   

    function _putPix(x,y,  r,g,b,a){

        //Convert XY to index:
        var dex = ( (y*4) *_w) + (x*4);

        _[dex+0]   = r;
        _[dex+1]   = g;
        _[dex+2]   = b;
        _[dex+3]   = a;

    }

    function _apply(){
        _ctx.putImageData( _, 0,0 );  
    }

}

function backBufferTest(canvas_input, test_type){
    var can = canvas_input; //shorthand var.

    if(test_type==SLOW_TEST){
        var t = new T( can );

        //Iterate over entire canvas, 
        //and set pixels:
        var x0 = 0;
        var x1 = can.width - 1;

        var y0 = 0;
        var y1 = can.height -1;

        for(var x = x0; x <= x1; x++){
        for(var y = y0; y <= y1; y++){
            t.PutPix(
                x,y, 
                x%256, y%256,(x+y)%256, 255
            );
        }}//next X/Y

    }else
    if(test_type==FAST_TEST){
        var t = new T( can );

        //Iterate over entire canvas, 
        //and set pixels:
        var x0 = 0;
        var x1 = can.width - 1;

        var y0 = 0;
        var y1 = can.height -1;

        for(var x = x0; x <= x1; x++){
        for(var y = y0; y <= y1; y++){
            t.PutPix(
                x,y, 
                x%256, y%256,(x+y)%256, 255
            );
        }}//next X/Y

        //When done setting arbitrary pixels,
        //use the apply method to show them 
        //on screen:
        t.Apply();

    }
}

main();
</script>
</html>

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X