HTML5: Bilder Upload mit Verkleinerung auf Client Seite
Tutorial von Stefan Trost | 21.09.2016 um 22:29
Bilder und Fotos werden heutzutage immer größer - oft viel zu groß, um sie vernünftig auf einer Website ausgeben zu können. Nun ist es zwar möglich, die Bilder nach dem Upload mit PHP zu verkleinern, doch dies kann sehr ressourcenaufwändig sein und sollte daher in den meisten Fällen vermieden werden.
Aus diesem Grund habe ich kürzlich in einem Tutorial beschrieben, wie man ein Bild auch ohne serverseitiges PHP-Skript direkt clientseitig im Browser verkleinern kann, um es dann bereits verkleinert an den Server zu senden. Das dort vorgestellte Skript könnte allerdings immer nur ein Bild auf einmal hochladen. Nun möchte ich in diesem Tutorial erklären, wie man mehrere Bilder auf einmal uploaden kann.
Da die Skripte hier weitestgehend dem ersten Tutorial gleichen, möchte ich hier nur auf die Änderungen eingehen und für alle anderen Erklärungen auf das erste Tutorial (oben verlinkt) verweisen. Am Ende des Tutorials findet ihr natürlich auch diesen Code in voller Länge ohne dass ihr die Stücke selber zusammen fügen müsst.
HTML
In unserem HTML ist nur eine Änderung erforderlich. Wir fügen unserem File-Input das Attribut "multiple" hinzu.
<input id="inp_files" type="file" multiple="multiple">
Dadurch erlauben wir dem Nutzer eine Mehrfachauswahl von Dateien.
JavaScript
Auch der JavaScript-Code bleibt weitestgehend identisch. Im ersten Tutorial hatten wir die Dateien mit var file = e.target.files[0] ausgelesen. Damit hatten wir nur das erste Element des Arrays e.target.files ausgelesen (das erse Element hat den Index 0).
for (var i = 0; i < e.target.files.length; i++) { var file = e.target.files[i]; }
Da wir nun von einer beliebigen Anzahl von Dateien ausgehen, haben wir unseren Code um eine Schleife ergänzt, die bei 0 beginnt und die Anzahl der Dateien mit e.target.files.length berücksichtigt. Innerhalb der Schleife lesen wir dann die aktuelle Datei mit var file = e.target.files[i] aus und machen ansonsten weiter wie bisher.
document.getElementById('inp_img').value = dataURL; document.getElementById('inp_img').value += dataURL + '|';
Während wir ersten Tutorial die Base64-codierte dataURL direkt im Feld gespeichert haben, hängen wir die Variablen nun hinten an den bestehenden Inhalt des Feldes an. Wir benutzen dafür das Trennzeichen "|", so dass wir mehrere Bilder in dem Feld speichern können.
PHP
Auch unseren PHP-Code haben wir durch eine Schleife erweitert. Zunächst benutzen wir aber die explode() Funktion, um die aneinander gehängten Bilder wieder zu trennen. Danach gehen wir mit der Schleife über alle einzelnen Einträge und speichern jedes Bild einzeln ab.
$img = explode('|', $_POST['img']); for ($i = 0; $i < count($img) - 1; $i++) { $image = $img[$i]; // ... $file = 'uploads/img'.date("YmdHis").'_'.$i.$ext; // ... }
Damit die Bilder später nicht alle den gleichen Namen haben und sich gegenseitig überschreiben, hängen wir außerdem noch $i als Bild-Nummer an.
Die komplette Seite
Zuletzt findet ihr hier die komplette geänderte und angepasste Seite, für den Mehrfach-Bild-Upload. Diese Seite enthält den kompletten erforderlichen HTML, PHP und JavaScript-Code.
<!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> </head><body> <?php if (count($_POST)) { $img = explode('|', $_POST['img']); for ($i = 0; $i < count($img) - 1; $i++) { if (strpos($img[$i], 'data:image/jpeg;base64,') === 0) { $img[$i] = str_replace('data:image/jpeg;base64,', '', $img[$i]); $ext = '.jpg'; } if (strpos($img[$i], 'data:image/png;base64,') === 0) { $img[$i] = str_replace('data:image/png;base64,', '', $img[$i]); $ext = '.png'; } $img[$i] = str_replace(' ', '+', $img[$i]); $data = base64_decode($img[$i]); $file = 'uploads/img'.date("YmdHis").'_'.$i.$ext; if (file_put_contents($file, $data)) { echo "<p>Bild $i wurde gespeichert als $file.</p>"; } else { echo '<p>Bild $i konnte nicht gespeichert werden.</p>'; } } } ?> <input id="inp_files" type="file" multiple="multiple"> <form method="post" action=""> <input id="inp_img" name="img" type="hidden" value=""> <input id="bt_save" type="submit" value="Upload"> </form> <script> function fileChange(e) { document.getElementById('inp_img').value = ''; for (var i = 0; i < e.target.files.length; i++) { var file = e.target.files[i]; if (file.type == "image/jpeg" || file.type == "image/png") { var reader = new FileReader(); reader.onload = function(readerEvent) { var image = new Image(); image.onload = function(imageEvent) { var max_size = 300; var w = image.width; var h = image.height; if (w > h) { if (w > max_size) { h*=max_size/w; w=max_size; } } else { if (h > max_size) { w*=max_size/h; h=max_size; } } var canvas = document.createElement('canvas'); canvas.width = w; canvas.height = h; canvas.getContext('2d').drawImage(image, 0, 0, w, h); if (file.type == "image/jpeg") { var dataURL = canvas.toDataURL("image/jpeg", 1.0); } else { var dataURL = canvas.toDataURL("image/png"); } document.getElementById('inp_img').value += dataURL + '|'; } image.src = readerEvent.target.result; } reader.readAsDataURL(file); } else { document.getElementById('inp_files').value = ''; alert('Bitte wählen Sie nur Bilder im JPG- oder PNG-Format aus.'); return false; } } } document.getElementById('inp_files').addEventListener('change', fileChange, false); </script> </body></html>
Ihr könnt die Seite zum Beispiel als upload_resize_multiple.php abspeichern.
Über den Autor
Software von Stefan Trost finden Sie auf sttmedia.de. Benötigen Sie eine individuelle Software nach Ihren eigenen Wünschen? Schreiben Sie uns: sttmedia.de/kontakt
Profil anzeigen
Ähnliche Themen
Bild vor dem Upload im Browser verkleinern
Tutorial | 5 Kommentare
HTML5 Canvas: Einsteiger Tutorial Teil 1 - Einführung
Tutorial | 0 Kommentare
HTML5 Canvas als Bild an Server senden und speichern
Tutorial | 0 Kommentare
jQuery: HTML5 Canvas mit Ajax an Server senden
Tutorial | 0 Kommentare
Android Programmierung: Response von HTTP POST Request empfangen
Tutorial | 3 Kommentare
Bilder, CSS, JS und Seiten neu laden trotz Browser-Cache
Tipp | 2 Kommentare
HTML5 Canvas: Einsteiger Tutorial Teil 2 - Linien zeichnen
Tutorial | 0 Kommentare
Wichtiger Hinweis
Bitte beachten Sie: Die Beiträge auf askingbox.de sind Beiträge von Nutzern und sollen keine professionelle Beratung ersetzen. Sie werden nicht von Unabhängigen geprüft und spiegeln nicht zwingend die Meinung von askingbox.de wieder. Mehr erfahren.
Jetzt mitmachen
Stellen Sie Ihre eigene Frage oder schreiben Sie Ihren eigenen Artikel auf askingbox.de. So gehts.
Vielen Dank für diesen interessanten Beitrag - genau das was ich gesucht habe.
Die Verkleinerung funktioniert bei mir bereits bestens, mit einer Ausnahme: Teilweise kommt es vor, dass das Bild "auf den Kopf" gedreht wird. Gibt es hier eine Möglichkeit, dies zu umgehen, bzw. woran könnte das liegen?
Gruß Lukas
09.06.2018 um 21:14
Ich glaube nicht, dass die Drehung an diesem Script liegt.
Vermutlich liegt es an deinem Bildbetrachter / deiner Kamera. Insbesondere Handys machen es manchmal so, dass Sie alle Bilder zum Beispiel im Querformat speichern und dann nur als Metainformation dazu speichern, dass das Bild gedreht angezeigt werden soll.
Wenn du das Bild mit diesem Script bearbeitest, geht die Metainfo entsprechend verloren und das Bild zeigt sich in seiner Originaldrehung.
09.06.2018 um 23:37
Danke, möchte gerne 2x Upload einsetzten, leider geht nur einer?
Können Sie mir helfen?
Gruß Namrenner
20.04.2019 um 06:51
Ich möchte der Funktion fileChange(e) gerne unterschiedliche max_size übergeben (im Script fixiert auf 300).
Wie kann ich Werte übergeben, wo doch beim Aufruf noch nicht mal e übergeben wird?!?! Was ist das e und woher kommt es?
09.07.2019 um 21:20
Sehr guter Artikel.
Bei mir werden nicht alle ausgewählten Dateien übertragen. Es hängt offenbar mit der Dateigröße zusammen.
15.10.2019 um 17:14
Gigantisch.
Das ist eines der besten Scripte die ich je gefunden habe!
Vielen Dank!
11.02.2020 um 15:59