338 Stimmen

Größenänderung eines Bildes in einem HTML5-Canvas

Ich versuche, ein Thumbnail-Bild auf der Client-Seite mit Javascript und ein Canvas-Element zu erstellen, aber wenn ich das Bild zu verkleinern, sieht es schrecklich. Es sieht aus, als ob es in Photoshop mit dem Resampling auf "Nearest Neighbor" anstelle von Bicubic verkleinert wurde. Ich weiß, dass es möglich ist, dies richtig aussehen zu lassen, weil diese Seite kann das auch mit einer Leinwand gut machen. Ich habe versucht, den gleichen Code zu verwenden, wie er im Link "[Quelle]" gezeigt wird, aber es sieht immer noch schrecklich aus. Gibt es etwas, das ich vermisse, eine Einstellung, die festgelegt werden muss oder etwas?

EDIT :

Ich versuche, die Größe eines jpg zu ändern. Ich habe versucht, die Größe desselben jpg auf der verlinkten Website und in Photoshop zu ändern, und es sieht gut aus, wenn es verkleinert wird.

Hier ist der entsprechende Code:

reader.onloadend = function(e)
{
    var img = new Image();
    var ctx = canvas.getContext("2d");
    var canvasCopy = document.createElement("canvas");
    var copyContext = canvasCopy.getContext("2d");

    img.onload = function()
    {
        var ratio = 1;

        if(img.width > maxWidth)
            ratio = maxWidth / img.width;
        else if(img.height > maxHeight)
            ratio = maxHeight / img.height;

        canvasCopy.width = img.width;
        canvasCopy.height = img.height;
        copyContext.drawImage(img, 0, 0);

        canvas.width = img.width * ratio;
        canvas.height = img.height * ratio;
        ctx.drawImage(canvasCopy, 0, 0, canvasCopy.width, canvasCopy.height, 0, 0, canvas.width, canvas.height);
    };

    img.src = reader.result;
}

EDIT2:

Anscheinend habe ich mich geirrt, denn die verlinkte Website hat das Bild auch nicht besser verkleinert. Ich habe die anderen vorgeschlagenen Methoden ausprobiert, und keine von ihnen sieht besser aus. So sahen die verschiedenen Methoden aus:

Photoshop:

alt text

Segeltuch:

alt text

Bild mit image-rendering: optimizeQuality eingestellt und mit Breite/Höhe skaliert:

alt text

Bild mit image-rendering: optimizeQuality eingestellt und mit -moz-transform skaliert:

alt text

Größenänderung der Leinwand bei pixastic:

alt text

Ich schätze, das bedeutet, dass Firefox kein bikubisches Sampling verwendet, wie es eigentlich sein sollte. Ich werde einfach warten müssen, bis sie es tatsächlich hinzufügen.

EDIT3:

Originalbild

8voto

Christophe Marois Punkte 6041

Dies ist eine Javascript-Funktion, die aus dem Code von @Telanor übernommen wurde. Wenn ein Bild base64 als erstes Argument an die Funktion übergeben wird, gibt sie die base64 des Bildes mit veränderter Größe zurück. maxWidth und maxHeight sind optional.

function thumbnail(base64, maxWidth, maxHeight) {

  // Max size for thumbnail
  if(typeof(maxWidth) === 'undefined') var maxWidth = 500;
  if(typeof(maxHeight) === 'undefined') var maxHeight = 500;

  // Create and initialize two canvas
  var canvas = document.createElement("canvas");
  var ctx = canvas.getContext("2d");
  var canvasCopy = document.createElement("canvas");
  var copyContext = canvasCopy.getContext("2d");

  // Create original image
  var img = new Image();
  img.src = base64;

  // Determine new ratio based on max size
  var ratio = 1;
  if(img.width > maxWidth)
    ratio = maxWidth / img.width;
  else if(img.height > maxHeight)
    ratio = maxHeight / img.height;

  // Draw original image in second canvas
  canvasCopy.width = img.width;
  canvasCopy.height = img.height;
  copyContext.drawImage(img, 0, 0);

  // Copy and resize second canvas to first canvas
  canvas.width = img.width * ratio;
  canvas.height = img.height * ratio;
  ctx.drawImage(canvasCopy, 0, 0, canvasCopy.width, canvasCopy.height, 0, 0, canvas.width, canvas.height);

  return canvas.toDataURL();

}

7voto

Evan Carroll Punkte 1

Ich empfehle Ihnen dringend einen Blick auf ce lien und vergewissern Sie sich, dass sie auf true gesetzt ist.

Steuerung des Skalierungsverhaltens von Bildern

Eingeführt in Gecko 1.9.2 (Firefox 3.6 / Thunderbird 3.1 / Fennec 1.0)

Gecko 1.9 Eigenschaft mozImageSmoothingEnabled für das Canvas-Element eingeführt; wenn dieser boolesche Wert false ist, werden Bilder nicht Bilder beim Skalieren nicht geglättet. Diese Eigenschaft ist standardmäßig true. view plainprint?

  1. cx.mozImageSmoothingEnabled = false;

6voto

Xavi Punkte 19701

Wenn Sie einfach nur die Größe eines Bildes ändern wollen, empfehle ich die Einstellung width y height des Bildes mit CSS. Hier ist ein kurzes Beispiel:

.small-image {
    width: 100px;
    height: 100px;
}

Beachten Sie, dass die height y width kann auch mit JavaScript gesetzt werden. Hier ein kurzes Code-Beispiel:

var img = document.getElement("my-image");
img.style.width = 100 + "px";  // Make sure you add the "px" to the end,
img.style.height = 100 + "px"; // otherwise you'll confuse IE

Um sicherzustellen, dass das Bild in der neuen Größe gut aussieht, fügen Sie die folgenden CSS-Regeln zum Bildselektor hinzu:

Soweit ich weiß, verwenden alle Browser außer dem IE standardmäßig einen bikubischen Algorithmus zur Größenanpassung von Bildern, so dass Ihre angepassten Bilder in Firefox und Chrome gut aussehen sollten.

Wenn die Einstellung der css width y height nicht funktioniert, können Sie mit einer css transform :

Wenn Sie aus irgendeinem Grund brauchen Wenn Sie ein Canvas verwenden möchten, beachten Sie bitte, dass es zwei Möglichkeiten gibt, die Größe eines Bildes zu ändern: durch Ändern der Größe des Canvas mit css oder durch Zeichnen des Bildes in einer kleineren Größe.

見る diese Frage für weitere Einzelheiten.

5voto

robert Punkte 4583

Ich habe dieses Bild durch Rechtsklick auf das Canvas-Element in Firefox und Speichern unter erhalten.

alt text

var img = new Image();
img.onload = function () {
    console.debug(this.width,this.height);
    var canvas = document.createElement('canvas'), ctx;
    canvas.width = 188;
    canvas.height = 150;
    document.body.appendChild(canvas);
    ctx = canvas.getContext('2d');
    ctx.drawImage(img,0,0,188,150);
};
img.src = 'original.jpg';

Wie auch immer, hier ist eine "korrigierte" Version Ihres Beispiels:

var img = new Image();
// added cause it wasnt defined
var canvas = document.createElement("canvas");
document.body.appendChild(canvas);

var ctx = canvas.getContext("2d");
var canvasCopy = document.createElement("canvas");
// adding it to the body

document.body.appendChild(canvasCopy);

var copyContext = canvasCopy.getContext("2d");

img.onload = function()
{
        var ratio = 1;

        // defining cause it wasnt
        var maxWidth = 188,
            maxHeight = 150;

        if(img.width > maxWidth)
                ratio = maxWidth / img.width;
        else if(img.height > maxHeight)
                ratio = maxHeight / img.height;

        canvasCopy.width = img.width;
        canvasCopy.height = img.height;
        copyContext.drawImage(img, 0, 0);

        canvas.width = img.width * ratio;
        canvas.height = img.height * ratio;
        // the line to change
        // ctx.drawImage(canvasCopy, 0, 0, canvasCopy.width, canvasCopy.height, 0, 0, canvas.width, canvas.height);
        // the method signature you are using is for slicing
        ctx.drawImage(canvasCopy, 0, 0, canvas.width, canvas.height);
};

// changed for example
img.src = 'original.jpg';

4voto

Yaffle Punkte 299

Für die Größenänderung auf ein Bild mit einer geringeren Breite als das Original, verwende ich:

    function resize2(i) {
      var cc = document.createElement("canvas");
      cc.width = i.width / 2;
      cc.height = i.height / 2;
      var ctx = cc.getContext("2d");
      ctx.drawImage(i, 0, 0, cc.width, cc.height);
      return cc;
    }
    var cc = img;
    while (cc.width > 64 * 2) {
      cc = resize2(cc);
    }
    // .. than drawImage(cc, .... )

und es funktioniert =).

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