Erstellen Sie ein Bildausschnitttool mit HTML5

JavaScriptBeginner
Jetzt üben

Einführung

Dieses Projekt führt Sie durch den Prozess der Erstellung eines einfachen Bildausschnittswerkzeugs. Am Ende werden Sie eine interaktive Anwendung haben, die Benutzern ermöglicht, Bilder hochzuladen, anzuzeigen und auszuschneiden.

👀 Vorschau

Image cropping tool demo

🎯 Aufgaben

In diesem Projekt lernen Sie:

  • Wie Sie die HTML-Struktur für das Bildausschnittswerkzeug erstellen
  • Wie Sie die Webseite mit CSS gestalten, um sie visuell ansprechend zu machen
  • Wie Sie Variablen und Ereignislistener mit JavaScript initialisieren, um Benutzerinteraktionen zu verarbeiten
  • Wie Sie das Hochladen und Anzeigen von Bildern mit der FileReader-API in JavaScript behandeln
  • Wie Sie den Ausschnittmechanismus mit der Canvas-API in JavaScript implementieren
  • Wie Sie das ausgeschnittene Bild speichern und das Ergebnis anzeigen

🏆 Errungenschaften

Nach Abschluss dieses Projekts werden Sie in der Lage sein:

  • HTML-Tags und -Struktur zu verstehen
  • CSS-Eigenschaften und -Selektoren effektiv anzuwenden
  • Die JavaScript-Syntax, Variablen und Ereignislistener zu nutzen
  • Die FileReader-API in JavaScript für das Behandeln von Dateiuploads zu nutzen
  • Bildbearbeitung mit der Canvas-API in JavaScript umzusetzen

Aufbauen Sie die HTML-Struktur

Anforderungen:

  • Kenntnisse von HTML-Tags und -Struktur.

Funktionalität:

  • Entwerfen Sie eine Schnittstelle, die Benutzern ermöglicht, ein Bild hochzuladen und den Ausschnittprozess auszulösen.

Fügen Sie den HTML-Code in Ihre index.html ein.

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>HTML5 Crop Image</title>
    <link rel="stylesheet" href="style.css" />
  </head>
  <body>
    <input type="file" name="file" id="post_file" />

    <button id="save_button">SAVE</button>
    <div id="label">
      <canvas id="get_image"></canvas>
      <p>
        <canvas id="cover_box"></canvas>
        <canvas id="edit_pic"></canvas>
      </p>
    </div>
    <p>
      <span id="show_edit"></span>
      <span id="show_pic"><img src="" /></span>
    </p>
    <script type="text/javascript" src="main.js"></script>
  </body>
</html>

Die drei oben genannten <canvas>-Tags werden verwendet, um Inhalte im Zusammenhang mit Bildern zu verarbeiten. Die detaillierte Behandlung wird im nachfolgenden js (JavaScript)-Code bereitgestellt. Die Elemente mit der ID show_edit und der ID show_pic dienen zur Vorschau des Bilds und zum Anzeigen des Endresultats der Bildgenerierung.

✨ Lösung prüfen und üben

Stilieren Sie die Webseite

Anforderungen:

  • Vertrautheit mit CSS-Eigenschaften und -Selektoren.

Funktionalität:

  • Gestalten Sie die HTML-Elemente, um die Schnittstelle benutzerfreundlich und visuell ansprechend zu machen.

Fügen Sie den CSS-Code in Ihre style.css ein.

body {
  background-color: #f6f6f6;
  margin: 0;
  padding: 20px;
  text-align: center;
}

#label {
  border: 1px solid #ccc;
  background-color: #fff;
  text-align: center;
  height: 300px;
  width: 300px;
  margin: 20px auto;
  position: relative;
}

#get_image {
  position: absolute;
}

#edit_pic {
  position: absolute;
  display: none;
  background: #000;
}

#cover_box {
  position: absolute;
  z-index: 9999;
  display: none;
  top: 0px;
  left: 0px;
}

#show_edit {
  margin: 0 auto;
  display: inline-block;
}

#show_pic {
  height: 100px;
  width: 100px;
  border: 2px solid #000;
  overflow: hidden;
  margin: 0 auto;
  display: inline-block;
}

canvas {
  position: absolute;
  top: 0;
  left: 0;
}

#save_button {
  padding: 8px 16px;
  background-color: #3498db;
  color: #fff;
  border: none;
  border-radius: 5px;
  cursor: pointer;
  transition: background-color 0.2s;
}

#save_button:hover {
  background-color: #2980b9;
}

input[type="file"] {
  margin-bottom: 20px;
}
✨ Lösung prüfen und üben

Initialisieren Sie Variablen und Ereignislistener

Anforderungen:

  • Grundlegendes Verständnis der JavaScript-Syntax, -Variablen und -Ereignislistener.

Funktionalität:

  • Initialisieren Sie Eigenschaften und Konfigurationen für das Bildausschnittswerkzeug. Fügen Sie einen Ereignislistener hinzu, um das hochgeladene Bild zu verarbeiten.

In main.js schreiben Sie den Code, um die Eigenschaften des Bildausschnittswerkzeugs zu initialisieren und Ereignislistener einzurichten.

var postFile = {
  init: function () {
    var t = this;
    t.regional = document.getElementById("label");
    t.getImage = document.getElementById("get_image");
    t.editPic = document.getElementById("edit_pic");
    t.editBox = document.getElementById("cover_box");
    t.px = 0; //background image x
    t.py = 0; //background image y
    t.sx = 15; //crop area x
    t.sy = 15; //crop area y
    t.sHeight = 150; //crop area height
    t.sWidth = 150; //crop area width
    document
      .getElementById("post_file")
      .addEventListener("change", t.handleFiles, false);
  }
};

Alle unsere Funktionen und Variablen sind in das postFile-Objekt kapselt. Die oben erwähnte init-Funktion setzt hauptsächlich einige Anfangswerte.

t.px = 0;
t.py = 0;
t.sx = 15;
t.sy = 15;
t.sHeight = 100;
t.sWidth = 100;

Die Variablen t.px und t.py repräsentieren die Koordinaten des Hintergrundbilds im Echtzeitvorschaubereich; t.sx, t.sy, t.sHeight und t.sWidth repräsentieren die x- und y-Koordinaten sowie die Breite und Höhe des Bilds.

Wir erhalten auch mehrere Elemente, auf die wir später operieren werden, über document.getElementById.

document
  .getElementById("post_file")
  .addEventListener("change", t.handleFiles, false);

Wir hören auf das change-Ereignis des input-Formulars mit der id post_file, um die von den Benutzern hochgeladenen Dateien zu verarbeiten. Hier delegieren wir dies an die handleFiles-Funktion. Also implementieren wir als nächstes die handleFiles-Funktion.

✨ Lösung prüfen und üben

Behandeln Sie das Bildhochladen und die Anzeige

Anforderungen:

  • Grundkenntnisse der FileReader-API in JavaScript.

Funktionalität:

  • Stellen Sie sicher, dass wenn Benutzer ein Bild hochladen, es richtig verarbeitet, gelesen und auf dem Bildschirm angezeigt wird.

Erweitern Sie Ihre main.js um die Funktionen, um das hochgeladene Bild zu verarbeiten und anzuzeigen.

  1. Um die handleFiles-Funktion zu implementieren

Hier verwenden wir die HTML5-File-API. Zunächst instanziieren wir mithilfe von new FileReader() ein FileReader-Objekt namens oFReader. Anschließend rufen wir seine readAsDataURL()-Methode auf, um den Dateiinhalt zu lesen und ihn in ein base64-codiertes Format zu konvertieren.

Schließlich, wenn die Datei vollständig gelesen und geladen ist, verarbeiten wir das gelesene Bild mit postFile.paintImage(oFREvent.target.result). Einfach ausgedrückt zeichnen wir die gelesenen Bilddaten erneut auf den Browser.

handleFiles: function () {
        var fileList = this.files[0];
        var oFReader = new FileReader();
        oFReader.readAsDataURL(fileList);
        oFReader.onload = function (oFREvent) {
            postFile.paintImage(oFREvent.target.result);
        };
},
  1. Um die paintImage-Funktion zu implementieren

Der wichtigste Schritt hier besteht darin, das Bild gemäß der Größe des Containers mit Hilfe von canvas zu zeichnen. Im vorherigen Schritt haben wir mithilfe der FileReader der File-API bereits die URL des Bilds erhalten, das wir hochladen möchten (der Wert von oFREvent.target.result). Der nächste Schritt besteht darin, mit canvas dieses Bild zu zeichnen. Zunächst verwenden wir getImage.getContext, um den 2D-Inhalt von <canvas id="get_image"></canvas> zu erhalten, was einfach als Bildinhalt verstanden werden kann. Danach erstellen wir mit new Image() ein <img>-Element und legen seinen src-Attributwert fest.

paintImage: function (url) {
        var t = this;
        var createCanvas = t.getImage.getContext("2d");
        var img = new Image();
        img.src = url;
        img.onload = function () {
            if (
                img.width < t.regional.offsetWidth &&
                img.height < t.regional.offsetHeight
            ) {
                t.imgWidth = img.width;
                t.imgHeight = img.height;
            } else {
                var pWidth = img.width / (img.height / t.regional.offsetHeight);
                var pHeight = img.height / (img.width / t.regional.offsetWidth);
                t.imgWidth = img.width > img.height? t.regional.offsetWidth : pWidth;
                t.imgHeight =
                    img.height > img.width? t.regional.offsetHeight : pHeight;
            }
            t.px = (t.regional.offsetWidth - t.imgWidth) / 2 + "px";
            t.py = (t.regional.offsetHeight - t.imgHeight) / 2 + "px";

            t.getImage.height = t.imgHeight;
            t.getImage.width = t.imgWidth;
            t.getImage.style.left = t.px;
            t.getImage.style.top = t.py;

            createCanvas.drawImage(img, 0, 0, t.imgWidth, t.imgHeight);
            t.imgUrl = t.getImage.toDataURL();
            t.cutImage();
            t.drag();
        };
},

Innerhalb der img.onload-Funktion ist unser Hauptziel, das Bild in seiner ursprünglichen Größe erneut zu zeichnen, während seine Proportionen beibehalten werden, weshalb wir eine if-Bedingung haben. Letztendlich verwenden wir die Zeile createCanvas.drawImage(img,0,0,t.imgWidth,t.imgHeight);, um das Bild tatsächlich zu rendern.

✨ Lösung prüfen und üben

Implementieren Sie den Zuschneide-Mechanismus

Anforderungen:

  • Vertrautheit mit der Canvas-API in JavaScript für das Zeichnen und die Bildbearbeitung.

Funktionalität:

  • Fügen Sie einen Ausschnittbereich auf dem angezeigten Bild hinzu und machen diesen Bereich verschiebbar. Dies gibt den Benutzern die Flexibilität, den gewünschten Bereich auszuwählen, den sie ausschneiden möchten.

Fügen Sie die relevanten Methoden in main.js hinzu.

  1. Erstellen Sie eine cutImage-Methode

Die cutImage-Methode ist hauptsächlich für zwei Aufgaben verantwortlich: eine ist es, eine Maskenschicht zu erstellen, und die andere ist es, mithilfe der CSS-background-Eigenschaft eine Echtzeitvorschau des ausgewählten Ausschnittbereichs bereitzustellen.

cutImage: function () {
        var t = this;

        t.editBox.height = t.imgHeight;
        t.editBox.width = t.imgWidth;
        t.editBox.style.display = "block";
        t.editBox.style.left = t.px;
        t.editBox.style.top = t.py;

        var cover = t.editBox.getContext("2d");
        cover.fillStyle = "rgba(0, 0, 0, 0.5)";
        cover.fillRect(0, 0, t.imgWidth, t.imgHeight);
        cover.clearRect(t.sx, t.sy, t.sHeight, t.sWidth);

        document.getElementById("show_edit").style.background =
            "url(" + t.imgUrl + ")" + -t.sx + "px " + -t.sy + "px no-repeat";
        document.getElementById("show_edit").style.height = t.sHeight + "px";
        document.getElementById("show_edit").style.width = t.sWidth + "px";
},
  1. Erstellen Sie eine drag-Methode
drag: function () {
        var t = this;
        var draging = false;
        var startX = 0;
        var startY = 0;

        document.getElementById("cover_box").onmousemove = function (e) {
            var pageX = e.pageX - (t.regional.offsetLeft + this.offsetLeft);
            var pageY = e.pageY - (t.regional.offsetTop + this.offsetTop);

            if (
                pageX > t.sx &&
                pageX < t.sx + t.sWidth &&
                pageY > t.sy &&
                pageY < t.sy + t.sHeight
            ) {
                this.style.cursor = "move";

                this.onmousedown = function () {
                    draging = true;

                    t.ex = t.sx;
                    t.ey = t.sy;

                    startX = e.pageX - (t.regional.offsetLeft + this.offsetLeft);
                    startY = e.pageY - (t.regional.offsetTop + this.offsetTop);
                };
                window.onmouseup = function () {
                    draging = false;
                };

                if (draging) {
                    if (t.ex + (pageX - startX) < 0) {
                        t.sx = 0;
                    } else if (t.ex + (pageX - startX) + t.sWidth > t.imgWidth) {
                        t.sx = t.imgWidth - t.sWidth;
                    } else {
                        t.sx = t.ex + (pageX - startX);
                    }

                    if (t.ey + (pageY - startY) < 0) {
                        t.sy = 0;
                    } else if (t.ey + (pageY - startY) + t.sHeight > t.imgHeight) {
                        t.sy = t.imgHeight - t.sHeight;
                    } else {
                        t.sy = t.ey + (pageY - startY);
                    }

                    t.cutImage();
                }
            } else {
                this.style.cursor = "auto";
            }
        };
},

Um diese Methode zu verstehen, müssen Sie die folgenden Schlüsselpunkte verstehen:

var pageX = e.pageX - (t.regional.offsetLeft + this.offsetLeft);
var pageY = e.pageY - (t.regional.offsetTop + this.offsetTop);

Mit den obigen beiden Zeilen Code erhalten wir die Entfernung zwischen der Maus und dem Hintergrundbild. e.pageX repräsentiert die Entfernung von der Maus bis zum linken Rand des Browsers, und t.regional.offsetLeft + this.offsetLeft berechnet die Entfernung vom Bild bis zum linken Rand des Browsers. Ähnlich kann die obere Entfernung abgeleitet werden.

 if ( pageX > t.sx && pageX < t.sx + t.sWidth && pageY > t.sy && pageY < t.sy + t.sHeight )

Nachdem Sie die Entfernung zwischen der Maus und dem Hintergrundbild verstanden haben, sollte dies leicht zu verstehen sein: Es bestimmt, ob die Maus innerhalb der Bereich des Bilds ist.

t.ex = t.sx;
t.ey = t.sy;

startX = e.pageX - (t.regional.offsetLeft + this.offsetLeft);
startY = e.pageY - (t.regional.offsetTop + this.offsetTop);

Diese beiden Codeausschnitte sind hervorzuheben. Die ersten beiden Zeilen verzeichnen die Koordinaten vom letzten Screenshot (oder wenn es keinen vorherigen gab, dann die Anfangskoordinaten); die nächsten beiden Zeilen verzeichnen die Koordinaten, wenn die Maus gedrückt wird. Sie können diese Werte separat mit console.log() überprüfen.

if (draging) {
  if (t.ex + (pageX - startX) < 0) {
    t.sx = 0;
  } else if (t.ex + (pageX - startX) + t.sWidth > t.imgWidth) {
    t.sx = t.imgWidth - t.sWidth;
  } else {
    t.sx = t.ex + (pageX - startX);
  }

  if (t.ey + (pageY - startY) < 0) {
    t.sy = 0;
  } else if (t.ey + (pageY - startY) + t.sHeight > t.imgHeight) {
    t.sy = t.imgHeight - t.sHeight;
  } else {
    t.sy = t.ey + (pageY - startY);
  }

  t.cutImage();
}

Der obige Code sagt im Wesentlichen: Wenn wir mitten im Ziehen sind, müssen wir die Werte von t.sx und t.sy in Echtzeit basierend auf den Koordinatenänderungen aktualisieren und die cutImage-Methode aufrufen, um eine Livevorschau bereitzustellen.

Die Koordinaten des Ausschnittbereichs während der Bewegung = letzte aufgezeichnete Position + (aktuelle Mausposition - Position, als die Maus gedrückt wurde)

✨ Lösung prüfen und üben

Speichern Sie das zugeschnittene Bild

Anforderungen:

  • Kenntnisse bei der Verwendung von canvas, um Bilddaten zu extrahieren und anzuzeigen.

Funktionalität:

  • Nachdem der gewünschte Bildbereich ausgeschnitten wurde, ermöglichen Sie es Benutzern, diesen ausgeschnittenen Bereich zu speichern und das Ergebnis auf dem Bildschirm anzuzeigen.

Verstärken Sie die Initialisierungsfunktion in main.js, um das Speichern des ausgeschnittenen Bilds zu behandeln.

var postFile = {
  init: function () {
    //...
    document.getElementById("save_button").onclick = function () {
      t.editPic.height = t.sHeight;
      t.editPic.width = t.sWidth;
      var ctx = t.editPic.getContext("2d");
      var images = new Image();
      images.src = t.imgUrl;

      images.onload = function () {
        ctx.drawImage(
          images,
          t.sx,
          t.sy,
          t.sHeight,
          t.sWidth,
          0,
          0,
          t.sHeight,
          t.sWidth
        );
        document.getElementById("show_pic").getElementsByTagName("img")[0].src =
          t.editPic.toDataURL();
      };
    };
  }
};
postFile.init();

Ähnlich wie beim Implementieren der paintImage-Methode hören wir zunächst auf das Click-Ereignis auf der Speichertaste. Anschließend verwenden wir die drawImage-Methode, um die ausgewählte Bildregion zu rendern. Schließlich verwenden wir die toDataURL-Methode, um das Bild in ein base64-codiertes Format zu konvertieren. Dieser Wert wird dann dem src-Attribut des img unter show_pic zugewiesen. Auf diese Weise wird das Bildausschnitt und -speichern abgeschlossen.

✨ Lösung prüfen und üben

Testen Sie das Tool

  • Öffnen Sie index.html in einem Webbrowser.
    open web
  • Hochladen Sie ein Bild und testen Sie die Ausschnittfunktionalität.
  • Der Effekt der Seite ist wie folgt:
    image cropping tool demo
✨ Lösung prüfen und üben

Zusammenfassung

Herzlichen Glückwunsch! Sie haben mithilfe von HTML5 und JavaScript ein grundlegendes Bildausschnitttool gebaut. Auf dieser Grundlage können Sie weitere fortgeschrittene Funktionen oder andere Bildbearbeitungstasks implementieren. Üben Sie sich, indem Sie das Tool erweitern oder andere Webanwendungsprojekte erkunden!