strukturag / libheif

libheif is an HEIF and AVIF file format decoder and encoder.
Other
1.76k stars 302 forks source link

libeheif.js very slow #545

Open mandys opened 3 years ago

mandys commented 3 years ago

Hey Team,

I am playing with the javascript version.

Using the library from here: https://strukturag.github.io/libheif/libheif.js

When I am trying to convert 1.6MB heic image ( taken from iPhone 11 ) into jpeg, it's taking a minimum of 6 secs ( on my iMac ). This is a little too slow for just 1 image.

Looking at the below code:

This particular line is taking about 6 seconds _this.imagedata = this.ctx.createImageData(w, h);

Is there a way to speed this up ?

CanvasDrawer.prototype.draw = function(image) {
    **const start = Date.now();**
    var w = image.get_width();
    var h = image.get_height();
    if (w != this.canvas.width || h != this.canvas.height ||
            !this.image_data) {
        this.canvas.width = w;
        this.canvas.height = h;
        if (w > document.body.clientWidth) {
            addClass(this.container, "flexible-size");
            this.container.style["padding-bottom"] = String(100 * (h / w)) + "%";
        } else {
            removeClass(this.container, "flexible-size");
            this.container.style["padding-bottom"] = "";
        }

        _this.image_data = this.ctx.createImageData(w, h);_
    **const millis = Date.now() - start;
    console.log(`seconds elapsed = ${Math.floor(millis / 1000)}`);**
        var image_data = this.image_data.data;
        // Start with a white image.
        for (var i=0; i<w*h; i++) {
            image_data[i*4+3] = 255;
        }
    }

    image.display(this.image_data, function(display_image_data) {
        hide("decoding");
        if (!display_image_data) {
            show("error-format");
            return;
        }

        show("container");
        if (saveSupported) {
            show("save-container");
        } else {
            hide("save-container");
        }
        if (window.requestAnimationFrame) {
            this.pending_image_data = display_image_data;
            window.requestAnimationFrame(function() {
                if (this.pending_image_data) {
                    this.ctx.putImageData(this.pending_image_data, 0, 0);
                    this.pending_image_data = null;
                }
            }.bind(this));
        } else {
            this.ctx.putImageData(display_image_data, 0, 0);
        }
    }.bind(this));
};

Thank you, Mandy

vaclavbenes commented 2 months ago

Is it possible get image array without processing ImageData?