web-dev-qa-db-fra.com

Image redimensionnant côté client avec JavaScript avant téléchargement sur le serveur

Je cherche un moyen de redimensionner une image côté client avec JavaScript (vraiment redimensionner, pas seulement changer la largeur et la hauteur).
Je sais qu’il est possible de le faire en Flash, mais je voudrais l’éviter si possible.

Existe-t-il un algorithme open source quelque part sur le Web?

143
geraud

Voici un résumé qui fait ceci: https://Gist.github.com/dcollien/312bce1270a5f511bf4a

(une version es6 et une version .js pouvant être incluses dans une balise script)

Vous pouvez l'utiliser comme suit:

<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>

Il inclut un ensemble de fonctions de détection de support et de polyfill afin de s’assurer qu’il fonctionne sur autant de navigateurs que possible.

(il ignore également les images gif - au cas où elles seraient animées)

101
dcollien

La réponse est oui: en HTML 5, vous pouvez redimensionner les images côté client à l'aide de l'élément canvas. Vous pouvez également prendre les nouvelles données et les envoyer à un serveur. Voir ce tutoriel:

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

58
Jeremy Usher

Si vous redimensionniez avant de téléverser, je viens de découvrir ceci http://www.plupload.com/

Il fait toute la magie pour vous dans n'importe quelle méthode imaginable.

Malheureusement, seul le navigateur Mozilla prend en charge le redimensionnement HTML5, mais vous pouvez rediriger d'autres navigateurs vers Flash et Silverlight.

Je viens d'essayer et cela a fonctionné avec mon Android!

J'utilisais http://swfupload.org/ en flash, le travail est très efficace, mais la taille du redimensionnement est très petite. (ne me souviens pas de la limite) et ne retourne pas en html4 lorsque le flash n’est pas disponible.

12
ignacio

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

Dans le navigateur moderne, vous pouvez utiliser canvas pour charger/enregistrer des données d'image. Mais vous devez garder à l’esprit plusieurs choses si vous redimensionnez l’image sur le client:

  1. Vous aurez seulement 8 bits par canal (jpeg peut avoir une meilleure plage dynamique, environ 12 bits). Si vous ne téléchargez pas de photos professionnelles, cela ne devrait pas être un problème.
  2. Faites attention à l'algorithme de redimensionnement. La plupart des redimensionneurs côté client utilisent des mathématiques triviales, et le résultat est pire que ce qu'il pourrait être.
  3. Vous devrez peut-être préciser l’image réduite.
  4. Si vous souhaitez réutiliser les métadonnées (exif et autres) de l'original, n'oubliez pas de supprimer les informations de profil de couleur. Parce que c'est appliqué lorsque vous chargez l'image sur la toile.
10
Vitaly

Peut-être avec la balise canvas (bien que ce ne soit pas portable). Il existe un blog sur la rotation d'une image avec canvas ici , je suppose que si vous pouvez la faire pivoter, vous pouvez la redimensionner. Peut-être que cela peut être un point de départ.

Voir cette bibliothèque aussi.

6
David V.

Vous pouvez utiliser un framework de traitement d’images javascript pour le traitement d’images côté client avant de télécharger l’image sur le serveur.

Ci-dessous, j'ai utilisé MarvinJ pour créer un code exécutable basé sur l'exemple de la page suivante: "Traitement des images côté client avant leur téléchargement sur un serveur"

Fondamentalement, j'utilise la méthode Marvin.scale (...) pour redimensionner l'image. Ensuite, je télécharge l'image en tant que blob (en utilisant la méthode image.toBlob () ). Le serveur répond en fournissant une URL de l'image reçue.

/***********************************************
 * 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>

Oui, avec les navigateurs modernes, c'est totalement faisable. Même faisable au point de télécharger le fichier spécifiquement en tant que fichier binaire après avoir effectué un nombre quelconque de modifications de la toile.

http://jsfiddle.net/bo40drmv/

(cette réponse est une amélioration de la réponse acceptée ici )

Gardez à l'esprit d'attraper le processus de soumission du résultat dans PHP avec quelque chose qui ressemble à:

//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);

Si quelqu'un s'inquiète du point de vue de Vitaly, vous pouvez essayer de redimensionner et de redimensionner le clavier de travail.

2
Tatarize