webentwicklung-frage-antwort-db.com.de

So dehnen Sie Bilder ohne Antialiasing

So bin ich kürzlich auf dieses Thema gestoßen: http://www.nicalis.com/index.php

Und ich war neugierig: Gibt es eine Möglichkeit, so etwas mit kleineren Bildern zu machen? Ich meine, es handelt sich um Pixelkunst, und anstatt ein Bild zu verwenden, bei dem jedes Pixel die Größe vervierfacht, könnten wir es nicht mit dem Code strecken? Also fing ich an zu versuchen, es möglich zu machen.

Ich habe CSS, Javascript und sogar HTML ausprobiert, von denen keines funktionierte. Sie alle verwischen wirklich sehr stark (wie folgt: http://jsfiddle.net/nUVJt/2/ ), was mich zu meiner Frage bringt: Können Sie ein Bild im Browser ohne Antialiasing ausdehnen?

Ich bin offen für alle Vorschläge, sei es eine Leinwand, jQuery, CSS3 oder was auch immer.

Danke für die Hilfe!

EDIT: Es gibt einen besseren Weg, dies jetzt zu tun! Ein etwas weniger hackiger Weg! Hier ist die Magie:

.pixelated {
    image-rendering: -moz-crisp-edges;
    image-rendering: -o-crisp-edges;
    image-rendering: -webkit-optimize-contrast;
    -ms-interpolation-mode: nearest-neighbor;
    image-rendering: pixelated;
}

Dadurch wird das Anti-Aliasing in allen modernen Browsern gestoppt. Es funktioniert sogar in IE7-8, aber nicht in 9, und ich kenne leider keine Möglichkeit, dies in 9 zu tun (abgesehen von dem unten beschriebenen Canvas-Hack). Es ist nicht einmal lustig, wie viel schneller es so ist als mit JS. Weitere Informationen dazu finden Sie hier: https://developer.mozilla.org/en-US/docs/CSS/Image-rendering

EDIT2: Da dies noch keine offizielle Spezifikation ist, ist es nicht sehr zuverlässig. Chrome und FF scheinen beide nicht mehr unterstützt zu haben, seit ich oben geschrieben habe (laut diesem Artikel was unten erwähnt wurde), was wirklich ärgerlich ist. Wir werden wahrscheinlich noch ein paar Jahre warten müssen, bevor wir dies wirklich in CSS verwenden können, was wirklich bedauerlich ist.

FINIT EDIT: Es gibt einen offiziellen Weg, dies jetzt zu tun! Es gibt eine neue Eigenschaft namens image-rendering. Es ist in der CSS3-Spezifikation . Der Support ist super spotty im Moment, aber Chrome hat nur Support hinzugefügt So können wir image-rendering: pixelated; schon zu lange sagen, und es funktioniert an allen Stellen (yaayy immergrüne Browser!)

36
Timothy Miller

In der Canvas-Dokumentation wird explizit keine Skalierungsmethode angegeben - in meinen eigenen Tests hat das Bild in Firefox tatsächlich einen sehr schlechten Eindruck gemacht.

Der folgende Code kopiert Pixel für Pixel aus einem Quellbild (das aus demselben Ursprung oder aus einem Daten-URI stammen muss) und skaliert es um den angegebenen Faktor.

Um das ursprüngliche Quellbild zu empfangen, ist eine zusätzliche Leinwand außerhalb des Bildschirms (src_canvas) erforderlich. Die Bilddaten werden dann Pixel für Pixel in eine Leinwand auf dem Bildschirm kopiert.

var img = new Image();
img.src = ...;
img.onload = function() {

    var scale = 8;

    var src_canvas = document.createElement('canvas');
    src_canvas.width = this.width;
    src_canvas.height = this.height;

    var src_ctx = src_canvas.getContext('2d');
    src_ctx.drawImage(this, 0, 0);
    var src_data = src_ctx.getImageData(0, 0, this.width, this.height).data;

    var dst_canvas = document.getElementById('canvas');
    dst_canvas.width = this.width * scale;
    dst_canvas.height = this.height * scale;
    var dst_ctx = dst_canvas.getContext('2d');

    var offset = 0;
    for (var y = 0; y < this.height; ++y) {
        for (var x = 0; x < this.width; ++x) {
            var r = src_data[offset++];
            var g = src_data[offset++];
            var b = src_data[offset++];
            var a = src_data[offset++] / 100.0;
            dst_ctx.fillStyle = 'rgba(' + [r, g, b, a].join(',') + ')';
            dst_ctx.fillRect(x * scale, y * scale, scale, scale);
        }
    }
};

Arbeitsdemo unter http://jsfiddle.net/alnitak/LwJJR/

EDITEine optimalere Demo finden Sie unter http://jsfiddle.net/alnitak/j8YTe/ , die auch ein Rohdaten-Array für die Zielleinwand verwendet.

16
Alnitak

Ich habe es bekommen, um für die Leinwand zu arbeiten

var canvas = document.getElementById("canvas"),
    context = canvas.getContext('2d');
context.webkitImageSmoothingEnabled = context.imageSmoothingEnabled = context.mozImageSmoothingEnabled = context.oImageSmoothingEnabled = false;
3
Leonard Meagher

Der einzige Weg, den ich mir vorstellen kann, ist über Leinwand. Sie können einfach versuchen, das Bild auf eine Leinwand zu zeichnen und dann die Leinwand zu skalieren - ich denke , dass Sie auf diese Weise kein Anti-Aliasing erhalten. Wenn Sie dies dennoch tun, können Sie entweder versuchen, das Bild im Zeichenaufruf zu skalieren, oder wenn , das nicht funktioniert, getImageData verwenden. und putImageData um das Bild "von Hand" zu skalieren

update: Erste Methode funktioniert: http://jsfiddle.net/nUVJt/3/

1
Mark Kahn

ich bin nicht sicher, aber vielleicht können Sie Imagedata verwenden. probiere diese Funktion aus ..

function imageToImageData(image) {
     var canvas = document.createElement("canvas");
     canvas.width = image.width;
     canvas.height = image.height;
     var ctx = canvas.getContext("2d");
     ctx.drawImage(image, 0, 0);
     return ctx.getImageData(0, 0, canvas.width, canvas.height);
}
0
Salt Hareket

Nee. Der Browser macht dies jedoch so, und Sie haben keine Kontrolle über Skalierungsalgorithmen.

Ich bin mir jedoch sicher, dass es eine auf Leinwand basierende Lösung gibt, die Sie erstellen könnten. Dazu müssten Sie jedoch wahrscheinlich Pixel aus einem Quellbild kopieren und sie strategisch in die Leinwand zeichnen. Es wäre schwierig, aber möglich (und langsam).

0
Alex Wayne