Make HTML5 FileReader working with heic files

Sascha Grindau picture Sascha Grindau · Jul 20, 2019 · Viewed 7.4k times · Source

When reading a file from the input element by the FileReader api it works, but my android device also allows sending files and it seems to send heic files anyway which then results in an empty image without any errors in the console. Also the orientation is wrong when getting an image directly from the camera. I just found heavy librarys to implement and i am looking for a smarter solution.

JavaScript

function previewFile( e ) {
    var preview = document.getElementById('usersProfilePicture');
    var file    = e.files[0];
    var reader  = new FileReader();

    reader.onloadend = function () {
        preview.src = reader.result;
    }
    if (file) {
        reader.readAsDataURL(file);
    } else {
        preview.src = "";
    }
}

HTML5

<form>
    <label>
        <input id="uploadProfilePicture" name=file type=file accept="image/jpg, image/jpeg, image/png, image/gif, image/bmp">
    </label>
</form>

There are no error messages at all. Firefox, Chrome both on desktop and android allow .heic files no matter what accept attribute i set.

worst solution: deny acceptance of .heic files best solution: make fileReader work with .heic files. in between solution: detect heic and convert it to jpeg, clientside.

Answer

Paul Kolesar picture Paul Kolesar · Jan 15, 2020

I have a workaround for this issue for now by using the library heic2any

(https://github.com/alexcorvi/heic2any)

check to see if file from input is .heic, then use library like so:

heic2any({
        // required: the HEIF blob file
        blob: file,
        // (optional) MIME type of the target file
        // it can be "image/jpeg", "image/png" or "image/gif"
        // defaults to "image/png"
        toType: "image/jpeg",
        // conversion quality
        // a number ranging from 0 to 1
        quality: 0.5
    })

I wrap this call in a promise and then pass the result to the file reader:

// uploadHEIC is a wrapper for heic2any
uploadHEIC(heicFile).then(function (heicToJpgResult) {
    var reader = new Filereader();
    reader.onload = function () {
    // Do what you want to file
    }
    reader.readAsArrayBuffer(heicToJpgResult);
}