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 :

ember-js-redimensionnment-image-a-la-volee

Pour résumer donc :

  1. Notre input[file] nous fournit une image
  2. Un FileReader nous fournit l'image en base64
  3. 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 :

https://ember-twiddle.com/437c2a5976af4adcf8b0efb55df84d96