Voici un petit "tips", à défaut d'avoir le temps d'écrire un article...
Comment redimensionner une image avant upload ou pour d'autre besoins via Javascript ?
Il existe d'autres articles sur internet qui traite du sujet, l'idée de ce petit "article" était plus de montrer comment il est possible d'intégrer ces exemples dans une application Ember.js.
Fonctionnement
Le but de cet exemple est d'utiliser un input
de type file
pour permettre à l'utilisateur de fournir une image. Une fois qu'une image est sélectionnée, elle sera chargée via un FileReader
puis redimensionnée à l'aide d'un canvas
.
Voici le fonctionnement attendu :
Pour résumer donc :
- Notre
input[file]
nous fournit une image - Un
FileReader
nous fournit l'image en base64 - On utilise un
canvas
pour générer une version redimensionner de notre image en base64.
Le code
Notre controller
import Ember from 'ember';
import fileReader from '../misc/file-reader';
import imageResize from '../misc/image-resize';
export default Ember.Controller.extend({
imageBase64Data: null,
imageError: function(){
this.set('imageBase64Data', null);
alert("Erreur de chargement de l'image...");
},
actions: {
fileChange: async function(files){
if (files.length) {
//On charge le ficher sélectionné via un FileReader
try{
let imageBase64 = await fileReader(files[0]);
let imageResizeData = await imageResize(imageBase64, 250, 250, 0.5);
this.set('imageBase64Data', imageResizeData);
}
catch(e) {
this.imageError();
};
}
}
}
});
Le détails du fichier "image-resize.js"
import { Promise } from 'rsvp';
/**
* Redimensionnement d'une image
* Adapté à partir de : http://jsfiddle.net/Sk7LA/1035/
*
* @param {String} imageData Image d'origine en base 64
* @param {Number} maxWidth Largeur Max
* @param {Number} maxHeight Hauteur Max
* @param {String} [mimeType='image/jpeg'] Mime type pour l'image
* @param {Number} [quality=0.1] Qualité
* @return {String} Image image redimmensionnée en base 64
*
* @author jerome@mestres.fr
*/
export default function(imageData, maxWidth, maxHeight, quality = 1, mimeType = 'image/jpeg') {
var canvas = document.createElement("canvas");
return new Promise(function (resolve, reject) {
var img = document.createElement('img');
img.onload = function() {
//On détermine le ratio de scale
let scale = Math.min(maxWidth/this.width, maxHeight/this.height);
//On adapte la taille du canvas
canvas.width = this.width * scale;
canvas.height = this.height * scale;
//Puis on convertit
let context = canvas.getContext("2d");
context.scale( scale, scale);
context.drawImage(this, 0, 0);
let resizedImage = canvas.toDataURL(mimeType, quality);
canvas.remove();
img.remove();
resolve(resizedImage);
};
img.onerror = function() {
canvas.remove();
img.remove();
reject(this);
};
img.src = imageData;
});
}
Conclusion
Voici une méthode simple, rapide et surtout permettant de déléguer le redimensionnement d'une image à l'application front pour soulager nos petits serveurs VPS 😋...
Plus sérieusement, ce petit bout de code m'a permis de redimensionner une image dans une application qui doit pouvoir fonctionner en off-line mais également de convertir des images utilisateur en Jpeg (le canvas
tel qu'utilisé dans l'exemple nous fournit systématiquement une image Jpeg).
Le Twiddle
Comme d'habitude je vous ai fait un petit Twiddle qui reprend l'intégralité du code :