简体   繁体   中英

Extract exif data/rotate image added to fabric.js canvas

In my web app users can take photos on their phones from input type file.

Before I used js load image library to automatically detect EXIF data and rotate it if neccessary.

Now I've switched to fabric.js library because I want to allow users to draw on the canvas image before uploading it.

The problem is that I don't know how to get image exif data, or rotate the image when using fabric.js.

My code:

Getting the image from indexed db

var image;
localforage.getItem('photo').then(function(value) {
            image = value;

            // THIS IS OLD CODE, BEFORE I USER js-load-image to automatically detect exif data
            // and rotate if neccessary, then I just appended the result to wrapper
            // $("#preview-wrapper").empty();
            // if (image) {
            //    loadImage(
            //      image,
            //      function(img) {
            //        $("#preview-wrapper").append(img);
            //      },
            //      {orientation: true} // Options
            //    );
            // }

        })
 loadFabricOnImageLoad(); // append image to fabric canvas

Fabric.js function

function loadFabricOnImageLoad(){

    if(typeof image !== "undefined" && image){

        let loaded = false;
        if (loaded) {return;}
        var c = document.getElementById('myCanvas');
        canvas = new fabric.Canvas(c);
        canvas.setWidth(width);
        canvas.setHeight(500);
        canvas.selection = false;

        var url = URL.createObjectURL(image);

        fabric.Image.fromURL(url, function(img) {
            img.set({
                left: 0,
                right: 0,
                top: 0,
            });

            img.scaleToWidth(width);

            canvas.add(img);

            canvas.setHeight(img.getScaledHeight());

            $("#canvas-loader").hide();

        });  

        fabric.Object.prototype.set({
            evented: false
        });

        canvas.freeDrawingBrush = new fabric['PencilBrush'](canvas);
        canvas.freeDrawingBrush.color = 'Red';
        canvas.freeDrawingBrush.width = 6;

        loaded = true;
    } else {
        setTimeout(loadFabricOnImageLoad, 250);
    }
}

I've managed to do it myself after all by getting the exif data from image file:

localforage.getItem('photo').then(function(value) {
        image = value;

        // extract the exif data from image file using exif.js
        EXIF.getData(image, function() {
          let obj = EXIF.getAllTags(this);
          imageOrientation = obj.Orientation;
          console.log( imageOrientation );
        });

    })

I had to do a lot of scaling and resizing to get the size of rotated image and canvas correctly:

function loadFabricOnImageLoad(){

if(typeof image !== "undefined" && image){

    let loaded = false;
    if (loaded) {return;}
    var c = document.getElementById('myCanvas');
    canvas = new fabric.Canvas(c);
    canvas.setWidth(width);
    canvas.setHeight(500);
    canvas.selection = false;

    var url = URL.createObjectURL(image);

    fabric.Image.fromURL(url, function(img) {

        img.scaleToWidth(canvas.width);

        if(imageOrientation == 3 || imageOrientation == 6 || imageOrientation == 8) {
            img.scaleToHeight(canvas.height);

            canvas.setHeight(img.getScaledHeight());
            canvas.add(img);

            img.scaleToWidth(canvas.height);
        img.scaleToHeight(canvas.width);
        img.rotate(getDegreesForOrientation(imageOrientation));
            img.center();
        } else {
            canvas.setHeight(img.getScaledHeight());

            canvas.add(img);
        }


        $("#canvas-loader").hide();

    });
    // console.log('slika '+JSON.stringify(fabric.Image));


    fabric.Object.prototype.set({
        evented: false
    });

    canvas.freeDrawingBrush = new fabric['PencilBrush'](canvas);
    canvas.freeDrawingBrush.color = 'Red';
    canvas.freeDrawingBrush.width = 6;

    loaded = true;
} else {
    setTimeout(loadFabricOnImageLoad, 250);
}
}

I know this is already answered but I'd like to suggest different library. exif-js is dead - buggy and no longer maintained, with hundred of unsolved issues.

I would like you to try exifr which i started developing out of frustrations with exif-js.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM