DropZoneJS + JavascriptLoadImage: rotate image?
Asked Answered
O

4

5

I'm trying to combine DropZoneJS (found here) and JavascriptLoadImage (found here) to create a solution where a user can drag-drop a file to upload, and based on the EXIF metadata information in the image, it will rotate it (including the preview thumbnail) if necessary. I think that all of the necessary pieces are provided:

DropZoneJS provides the "addedfile" event which includes the file object. Hooking up that event handler, I can then pass its parameter to the JavascriptLoadImage.parseMetaData function and correctly read the stored orientation value:

var myDropZone = $("#my-awesome-dropzone").dropzone({ url: "/file/post" });

        myDropZone[0].dropzone.on("addedfile", function (file) {


//Successfully loads the image, flips it and sticks the resulting HTML5 canvas in the DOM for display.
            loadImage(file, function (img) {
                document.body.appendChild(img);
            },

            {
                orientation: 2,
                canvas:true
            }
            );


            loadImage.parseMetaData(file, function (data) {
                if (!data.imageHead) {
                    return;
                }
                var orientation = data.exif.get('Orientation');
            },
        {
            maxMetaDataSize: 262144,
            disableImageHead: false
        }
    );

        });

I can successfully do the rotation, but I'm not sure about taking the resulting canvas, and replacing the dropzone "file" objet with the resulting content.

  • Can anyone confirm if the "fileadded" event in DropzoneJS allows me to modify the file data (or if it's read only)

Thanks...

-Ben

Overeager answered 31/3, 2014 at 15:17 Comment(0)
L
3

1 - include https://raw.githubusercontent.com/jseidelin/exif-js/master/exif.js

2 - edit dropzone.js

  • Find & Add after img.onload = function() {

    var orientation = 0;
    EXIF.getData(img, function() {
        switch(parseInt(EXIF.getTag(this, "Orientation"))){
            case 3: orientation = 180; break;
            case 6: orientation = -90; break;
            case 8: orientation = 90; break; 
        }
    });
    
  • Replace > drawImageIOSFix(ctx to drawImageIOSFix(orientation, ctx

  • Find & Add after vertSquashRatio = detectVerticalSquash(img);

    dh = dh / vertSquashRatio;
    ctx.translate( dx+dw/2, dy+dh/2 );
    ctx.rotate(o*Math.PI/180);
    dx = -dw/2;
    dy = -dh/2;
    
Lunitidal answered 6/2, 2015 at 1:6 Comment(3)
The orientation for 6 and 8 in this are the wrong way round, 6 should be 90 and 8 should be -90. It is also more straightforward to put all this code in drawImageIOSFix rather than split it between functions. Sadly my edit fixing and tidying this up was rejected, though it didn't change the intent of the answer at all.Imitative
what if someone cannot edit the Dropzone.JS file. Like I'm using NodeJS system. any thoughts ?Hemispheroid
This does not work any more, because function "EXIF" is not defined.Pat
S
7

If you are using the latest Dropzone (tested with 5.4.0), it will automatically fix the orientation for thumbnails, as long as you include the exif.js library in your page:

https://github.com/exif-js/exif-js

I don't know why it works but it seems that Dropzone just "notices" it. I realized this after building a much more complex solution to achieve the same.

Please note that this does not affect the file sent to server, just the thumbnail Dropzone displays. I'm using ImageMagick -auto-orient to fix the uploaded file on the server.

Shoreless answered 25/5, 2018 at 20:56 Comment(0)
L
3

1 - include https://raw.githubusercontent.com/jseidelin/exif-js/master/exif.js

2 - edit dropzone.js

  • Find & Add after img.onload = function() {

    var orientation = 0;
    EXIF.getData(img, function() {
        switch(parseInt(EXIF.getTag(this, "Orientation"))){
            case 3: orientation = 180; break;
            case 6: orientation = -90; break;
            case 8: orientation = 90; break; 
        }
    });
    
  • Replace > drawImageIOSFix(ctx to drawImageIOSFix(orientation, ctx

  • Find & Add after vertSquashRatio = detectVerticalSquash(img);

    dh = dh / vertSquashRatio;
    ctx.translate( dx+dw/2, dy+dh/2 );
    ctx.rotate(o*Math.PI/180);
    dx = -dw/2;
    dy = -dh/2;
    
Lunitidal answered 6/2, 2015 at 1:6 Comment(3)
The orientation for 6 and 8 in this are the wrong way round, 6 should be 90 and 8 should be -90. It is also more straightforward to put all this code in drawImageIOSFix rather than split it between functions. Sadly my edit fixing and tidying this up was rejected, though it didn't change the intent of the answer at all.Imitative
what if someone cannot edit the Dropzone.JS file. Like I'm using NodeJS system. any thoughts ?Hemispheroid
This does not work any more, because function "EXIF" is not defined.Pat
M
2

First, thanks for your recommendation of the load image library, as I was looking for how to handle the EXIF data.

To answer your question: if you are talking about the thumbnail display, you can provide an "accept" function which receives the file, and a done function from dropzone itself, and display the thumbnail as needed.

I realized you might instead be asking about using the file from the load image library to upload. If that's the case, I would try to replace the file data in the accept function. The author of the load image library has a canvas to blob javascript as well that might help: https://github.com/blueimp/JavaScript-Canvas-to-Blob

Marchland answered 19/6, 2014 at 2:34 Comment(0)
C
0

I too have found that dropzone does not rotate thumbnails correctly. Here is my fix. Your project requires these npm packages: - dropzone - exif - blueimp-load-image

Blueimp load image is for scaling (creating a thumbnail) and it also handles exif infomation to properly rotate the image.

I solved my problem by creating a thumbnail with correct orientation and then simply replacing the img src of the thumbnail created by dropzone. Set the function createThumbnail as callback for the dropzone file added event:

createThumbnail: function(file){
            var scaledImage = loadImage.scale(
                file,
                {
                    maxWidth: 150,
                    imageOrientation: true
                }
            );
            $('[data-dz-thumbnail]').last().attr("src", scaledImage.dataURL);
        },
Canadianism answered 2/4, 2019 at 8:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.