wake-up-neo.com

Client-seitiges Ändern der Bildgröße mit JavaScript vor dem Hochladen auf den Server

Ich suche nach einer Möglichkeit, die Größe eines Bildes clientseitig mit JavaScript zu ändern (wirklich die Größe ändern, nicht nur Breite und Höhe ändern).
Ich weiß, dass es in Flash möglich ist, aber ich würde es gerne vermeiden, wenn es möglich ist.

Gibt es irgendwo im Web einen Open-Source-Algorithmus?

143
geraud

Hier ist eine Zusammenfassung, die dies tut: https://Gist.github.com/dcollien/312bce1270a5f511bf4a

(eine es6-Version und eine .js-Version, die in einem Skript-Tag enthalten sein kann)

Sie können es wie folgt verwenden:

<input type="file" id="select">
<img id="preview">
<script>
document.getElementById('select').onchange = function(evt) {
    ImageTools.resize(this.files[0], {
        width: 320, // maximum width
        height: 240 // maximum height
    }, function(blob, didItResize) {
        // didItResize will be true if it managed to resize it, otherwise false (and will return the original file as 'blob')
        document.getElementById('preview').src = window.URL.createObjectURL(blob);
        // you can also now upload this blob using an XHR.
    });
};
</script>

Es enthält eine Reihe von Unterstützungserkennungen und Polyfills, um sicherzustellen, dass es mit so vielen Browsern funktioniert, wie ich verwalten kann.

(GIF-Bilder werden ebenfalls ignoriert, falls sie animiert sind.)

101
dcollien

Die Antwort darauf lautet "Ja". In HTML 5 können Sie die Größe von Bildern mithilfe des canvas-Elements clientseitig ändern. Sie können die neuen Daten auch nehmen und an einen Server senden. Siehe dieses Tutorial:

http://hacks.mozilla.org/2011/01/how-to-develop-a-html5-image-uploader/

58
Jeremy Usher

Wenn Sie die Größe vor dem Hochladen geändert haben, habe ich dies gerade herausgefunden http://www.plupload.com/

Es macht die ganze Magie für Sie in jeder erdenklichen Methode.

Leider wird nur die Größenänderung in HTML5 mit Mozilla-Browsern unterstützt. Sie können jedoch andere Browser zu Flash und Silverlight umleiten.

Ich habe es gerade ausprobiert und es hat mit meinem Android funktioniert!

Ich habe http://swfupload.org/ in Flash verwendet, es macht den Job sehr gut, aber die Größe ist sehr klein. (Ich kann mich nicht an das Limit erinnern) und kehre nicht zu HTML4 zurück, wenn Flash nicht verfügbar ist.

12
ignacio

http://nodeca.github.io/pica/demo/

In modernen Browsern können Sie mithilfe der Zeichenfläche Bilddaten laden/speichern. Beachten Sie jedoch Folgendes, wenn Sie die Bildgröße auf dem Client ändern:

  1. Sie werden nur 8 Bit pro Kanal haben (JPEG kann einen besseren Dynamikbereich haben, ungefähr 12 Bit). Wenn Sie keine professionellen Fotos hochladen, sollte dies kein Problem sein.
  2. Seien Sie vorsichtig mit dem Größenänderungsalgorithmus. Die meisten clientseitigen Resizer verwenden triviale Mathematik, und das Ergebnis ist schlechter als es sein könnte.
  3. Möglicherweise müssen Sie das verkleinerte Bild schärfen.
  4. Wenn Sie Metadaten (exif und andere) aus dem Original wiederverwenden möchten, vergessen Sie nicht, die Farbprofilinformationen zu entfernen. Weil es angewendet wird, wenn Sie ein Bild auf eine Leinwand laden.
10
Vitaly

Vielleicht mit dem Canvas-Tag (obwohl es nicht portabel ist). Es gibt einen Blog darüber, wie man ein Bild mit der Leinwand dreht hier , ich nehme an, wenn Sie es drehen können, können Sie die Größe ändern. Vielleicht kann es ein Ausgangspunkt sein.

Siehe diese Bibliothek auch.

6
David V.

Sie können ein Javascript-Bildverarbeitungsframework für die clientseitige Bildverarbeitung verwenden, bevor Sie das Bild auf den Server hochladen.

Unten habe ich MarvinJ verwendet, um einen ausführbaren Code basierend auf dem Beispiel auf der folgenden Seite zu erstellen: "Verarbeiten von Bildern auf der Clientseite vor dem Hochladen auf einen Server"

Grundsätzlich benutze ich die Methode Marvin.scale (...) , um die Bildgröße zu ändern. Dann lade ich das Bild als Blob hoch (mit der Methode image.toBlob () ). Der Server antwortet mit einer URL des empfangenen Bildes.

/***********************************************
 * GLOBAL VARS
 **********************************************/
var image = new MarvinImage();

/***********************************************
 * FILE CHOOSER AND UPLOAD
 **********************************************/
 $('#fileUpload').change(function (event) {
        form = new FormData();
        form.append('name', event.target.files[0].name);
        
        reader = new FileReader();
        reader.readAsDataURL(event.target.files[0]);
        
        reader.onload = function(){
                image.load(reader.result, imageLoaded);
        };
        
});

function resizeAndSendToServer(){
  $("#divServerResponse").html("uploading...");
        $.ajax({
                method: 'POST',
                url: 'https://www.marvinj.org/backoffice/imageUpload.php',
                data: form,
                enctype: 'multipart/form-data',
                contentType: false,
                processData: false,
                
           
                success: function (resp) {
       $("#divServerResponse").html("SERVER RESPONSE (NEW IMAGE):<br/><img src='"+resp+"' style='max-width:400px'></img>");
                },
                error: function (data) {
                        console.log("error:"+error);
                        console.log(data);
                },
                
        });
};

/***********************************************
 * IMAGE MANIPULATION
 **********************************************/
function imageLoaded(){
  Marvin.scale(image.clone(), image, 120);
  form.append("blob", image.toBlob());
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://www.marvinj.org/releases/marvinj-0.8.js"></script>
<form id="form" action='/backoffice/imageUpload.php' style='margin:auto;' method='post' enctype='multipart/form-data'>
                                <input type='file' id='fileUpload' class='upload' name='userfile'/>
</form><br/>
<button type="button" onclick="resizeAndSendToServer()">Resize and Send to Server</button><br/><br/>
<div id="divServerResponse">
</div>

Ja, mit modernen Browsern ist dies völlig machbar. Selbst machbar, um die Datei spezifisch als Binärdatei hochzuladen, nachdem eine beliebige Anzahl von Canvas-Änderungen vorgenommen wurde.

http://jsfiddle.net/bo40drmv/

(Diese Antwort ist eine Verbesserung der akzeptierten Antwort hier )

Denken Sie daran, die Ergebnisübermittlung in PHP mit etwas ähnlichem zu verarbeiten:

//File destination
$destination = "/folder/cropped_image.png";
//Get uploaded image file it's temporary name
$image_tmp_name = $_FILES["cropped_image"]["tmp_name"][0];
//Move temporary file to final destination
move_uploaded_file($image_tmp_name, $destination);

Wenn Sie sich Gedanken über Vitalys Sinn machen, können Sie versuchen, die Größe der Arbeits-JFiddle etwas zu beschneiden und zu ändern.

2
Tatarize