Dropzone.js + redimensionnement de L'Image côté Client

je veux intégrer le Dropzone.js avec un redimensionnement de L'Image côté Client. Je sais qu'il y a une fonction pour redimensionner la miniature, mais je voudrais créer une fonction pour redimensionner l'image avant de le télécharger. Quelqu'un pourrait m'aider s'il vous plaît?

14
demandé sur Pedro Canelas 2013-12-12 05:12:11

5 réponses

Voici comment le faire sans télécharger le fichier de addedfile.

L'Important est de mettre autoQueue option false,dropzone pas de téléchargement automatique des fichiers sélectionnés par l'utilisateur.

var dropzone = new Dropzone (".dropzone", {
  ...
  autoQueue: false,
  ...
});

la prochaine étape est de faire redimensionner et de rechercher des versions redimensionnées dans addedfile événement.

dropzone.on("addedfile", function(origFile) {
  var MAX_WIDTH  = 800;
  var MAX_HEIGHT = 600;

  var reader = new FileReader();

  // Convert file to img

  reader.addEventListener("load", function(event) {

    var origImg = new Image();
    origImg.src = event.target.result;

    origImg.addEventListener("load", function(event) {

      var width  = event.target.width;
      var height = event.target.height;


      // Don't resize if it's small enough

      if (width <= MAX_WIDTH && height <= MAX_HEIGHT) {
        dropzone.enqueueFile(origFile);
        return;
      }


      // Calc new dims otherwise

      if (width > height) {
        if (width > MAX_WIDTH) {
          height *= MAX_WIDTH / width;
          width = MAX_WIDTH;
        }
      } else {
        if (height > MAX_HEIGHT) {
          width *= MAX_HEIGHT / height;
          height = MAX_HEIGHT;
        }
      }


      // Resize

      var canvas = document.createElement('canvas');
      canvas.width = width;
      canvas.height = height;

      var ctx = canvas.getContext("2d");
      ctx.drawImage(origImg, 0, 0, width, height);

      var resizedFile = base64ToFile(canvas.toDataURL(), origFile);


      // Replace original with resized

      var origFileIndex = dropzone.files.indexOf(origFile);
      dropzone.files[origFileIndex] = resizedFile;


      // Enqueue added file manually making it available for
      // further processing by dropzone

      dropzone.enqueueFile(resizedFile);
    });
  });

  reader.readAsDataURL(origFile);
});

Voici une fonction pour convertir dataURLdropzone fichier. Le processus pourrait être plus simple si vous utilisez toile.toBlob () au lieu de toile.toDataURL (), pour obtenir le contenu du fichier redimensionné, mais ce dernier n'est pas bien supporté par tous les navigateurs.

C'est juste une version modifiée de la fonction.

function base64ToFile(dataURI, origFile) {
  var byteString, mimestring;

  if(dataURI.split(',')[0].indexOf('base64') !== -1 ) {
    byteString = atob(dataURI.split(',')[1]);
  } else {
    byteString = decodeURI(dataURI.split(',')[1]);
  }

  mimestring = dataURI.split(',')[0].split(':')[1].split(';')[0];

  var content = new Array();
  for (var i = 0; i < byteString.length; i++) {
    content[i] = byteString.charCodeAt(i);
  }

  var newFile = new File(
    [new Uint8Array(content)], origFile.name, {type: mimestring}
  );


  // Copy props set by the dropzone in the original file

  var origProps = [ 
    "upload", "status", "previewElement", "previewTemplate", "accepted" 
  ];

  $.each(origProps, function(i, p) {
    newFile[p] = origFile[p];
  });

  return newFile;
}
12
répondu rodic 2017-08-02 11:50:37

la documentation de Dropzone sur la fonctionnalité de redimensionnement du pré-téléchargement est déroutante. La façon dont il lit, vous pouvez soit limiter la largeur, limiter la hauteur, ou limiter les deux et sacrifier le rapport D'Aspect, déformant l'image. Ce n'est pas le cas. Ceci:

resizeWidth: 1000, resizeHeight: 1000,
resizeMethod: 'contain', resizeQuality: 1.0,

limites largeur ou hauteur jusqu'à un maximum de 1000px-la plus grande des deux valeurs étant retenue. L'autre sera réduit en accord avec le rapport D'Aspect, sans déformer l'image. Ainsi, par exemple, dans mon test j'ai téléchargé un 2688x1512 image. Dropzone a recadré et redimensionné la vignette à sa valeur par défaut 120x120, mais le fichier envoyé au serveur a été redimensionné séparément par Dropzone, à 1000x562, puis envoyé au serveur.

il y a une mise en garde intéressante ici. Les JPEGs vont être recomprimés, avec une perte, donc même une resizeQuality de 1.0 va entraîner une perte. Je vois cette fonctionnalité comme une méthode pour empêcher les fichiers démesurément grands, mais vous devriez faire attention à redimensionner deux fois si vous pouvez l'éviter (une fois sur le serveur une fois sur client.)

si ce n'est pas assez pour vous - et que vous vouliez vraiment surcharger la méthode transform - il est intéressant de noter que suivre le chemin du code à L'intérieur de Dropzone est un peu confus, parce que le createThumbnail codepath est utilisé deux fois à chaque téléchargement, une fois pour créer une vignette comme vous vous y attendez, et encore une fois pour pré-redimensionner l'image ici avant de la Passer au serveur. De même, le resize méthode est prêter à confusion du nom; while resizeWidth etc référez-vous à la préparation de l'image pour télécharger, taille désigne le redimensionnement de l'image, et ne fait rien à l'image envoyée au serveur.

5
répondu Chris Moschini 2017-10-21 03:56:34

cela peut être fait en contournant le téléchargement fait par Dropzone.js. Pour cela, vous devez définir autoQueue: false dans les options (comme dans le Bootstrap exemple).

Ensuite, vous pouvez simplement envoyer la vignette, ou vous pouvez le faire à la dure.


Solution 1: Envoyer la vignette

myDropzone.on('thumbnail', function(file, dataURL) {
   $.post('http://example.com', {img: imgToSend})
})

vous pouvez définir la façon dont vous allez redimensionner/recadrer en ajoutant la fonction redimensionner dans les options.


Solution 2: redimensionner par vous-même

il y avait un autre problème: les images peuvent avoir besoin d'être tournées (cela arrive très souvent). Pour cela, la balise d'orientation EXIF doit être utilisée. Il est apparemment perdu lorsque vous redimensionnez, donc vous devez récupérer cette information dans le frontend, avant de redimensionner. Pour cela, j'ai utilisé le Exif.bibliothèque js.

Voici un exemple de travail sur JSFiddle. Vous pouvez voir L'URI de données de l'image redimensionnée dans votre console.

3
répondu Elzéar 2016-08-30 05:35:08

Dropzone version 5 est récemment publié, donc si vous passez à dropzone 5, alors vous pouvez simplement utiliser resizeWidth et resizeHeigh pour compresser votre image du côté du client.

si vous n'en fournissez qu'un, alors dropzone respectera le format d'origine, par exemple si vous ajoutez l'option: resizeWidth: 800

alors votre image sera compressée à Largeur = 800 pixels et la ration d'aspect de votre image originale sera respectée.

2
répondu Hooman 2017-07-13 23:00:53

Ok. Il m'a fallu un peu plus de temps pour trouver comment implémenter le redimensionnement.

Voici la solution finale qui fonctionne pour moi:

Import css and dropzone.js

<div class="row">
    <div class="col-sm-20 well">
        <form action="@Url.Action("_UploadImages", "Notebooks", new { unique = Model.UniqueId })" 
              method="post" 
              enctype="multipart/form-data"
              class="dropzone"
              id="my-dropzone"></form>
    </div>
</div>

<script type="text/javascript">
    Dropzone.options.myDropzone = {
        url: '@Url.Action("_UploadImages", "Notebooks", new { unique = Model.UniqueId })',
        autoProcessQueue: true,
        uploadMultiple: true,
        parallelUploads: 3,
        maxFilesize: 10,
        resizeWidth: 2048,
        addRemoveLinks: false,
        init: function () {
        }
    }
</script>
1
répondu HerGiz 2018-02-27 20:38:38