Search code examples
javascripthtmlimage-processingexif

HTML5 - resize image and keep EXIF in resized image


How can I resize an image (using an HTML5 canvas element) and keep the EXIF information from the original image? I can extract EXIF info from from original image but I don't know how to copy it to the resized image.

This is how I retrieve the resized image data to send to the server-side code:

canvas.toDataURL("image/jpeg", 0.7);

For EXIF retrieval, I'm using the exif.js library.


Solution

  • Working solution: ExifRestorer.js

    Usage with HTML5 image resize:

    function dataURItoBlob(dataURI) 
    {
        var binary = atob(dataURI.split(',')[1]);
        var array = [];
        for(var i = 0; i < binary.length; i++) {
            array.push(binary.charCodeAt(i));
        }
        return new Blob([new Uint8Array(array)], {type: 'image/jpeg'});
    }
    

    And main code, taken as part of HTML5 resizer from this page: https://github.com/josefrichter/resize/blob/master/public/preprocess.js (but slightly modified)

    var reader = new FileReader();
    
    //reader.readAsArrayBuffer(file); //load data ... old version
    reader.readAsDataURL(file);       //load data ... new version
    reader.onload = function (event) {
    // blob stuff
    //var blob = new Blob([event.target.result]); // create blob... old version
    var blob = dataURItoBlob(event.target.result); // create blob...new version
    window.URL = window.URL || window.webkitURL;
    var blobURL = window.URL.createObjectURL(blob); // and get it's URL
    
    // helper Image object
    var image = new Image();
    image.src = blobURL;
    
    image.onload = function() {
    
       // have to wait till it's loaded
       var resized = ResizeImage(image); // send it to canvas
    
       resized = ExifRestorer.restore(event.target.result, resized);  //<= EXIF  
    
       var newinput = document.createElement("input");
       newinput.type = 'hidden';
       newinput.name = 'html5_images[]';
       newinput.value = resized; // put result from canvas into new hidden input
       form.appendChild(newinput);
     };
    };