Resize a Base-64 image in JavaScript without using canvas

100,435

Solution 1

Ken's answer is the right answer, but his code doesn't work. I made some adjustments on it and it now works perfectly. To resize a Data URI :

// Takes a data URI and returns the Data URI corresponding to the resized image at the wanted size.
function resizedataURL(datas, wantedWidth, wantedHeight)
    {
        // We create an image to receive the Data URI
        var img = document.createElement('img');

        // When the event "onload" is triggered we can resize the image.
        img.onload = function()
            {        
                // We create a canvas and get its context.
                var canvas = document.createElement('canvas');
                var ctx = canvas.getContext('2d');

                // We set the dimensions at the wanted size.
                canvas.width = wantedWidth;
                canvas.height = wantedHeight;

                // We resize the image with the canvas method drawImage();
                ctx.drawImage(this, 0, 0, wantedWidth, wantedHeight);

                var dataURI = canvas.toDataURL();

                /////////////////////////////////////////
                // Use and treat your Data URI here !! //
                /////////////////////////////////////////
            };

        // We put the Data URI in the image's src attribute
        img.src = datas;
    }
// Use it like that : resizedataURL('yourDataURIHere', 50, 50);

Solution 2

Yes, you can. These solutions good for resizing not just converting image to base64.

  1. You can convert js file to image bitmap by jpg-js.And you can resize only by this lib, but in a case of resizing from very large image to very small, quality will be very bad.Best way for high-res images is to convert file to bitmap by jpg-js and then resize this bitmap by Pica lib.
  2. You can get image data from a file by jpg-js (or draw an image on canvas)and then resize canvasImageData by resizing lib pica. (good for High-resolution images, without canvas size restriction)
  3. You can use offscreen canvas, without attaching the canvas to a body, and resize an image. This solution will be faster but will be the worse solution for high-resolution images, for example 6000x6000 pixels. In that case, result canvas can be with bad quality or just empty, or browser can fall with memory limit exception. (good for normal and small images)

Jpg-js and Pica will not use dom elements at all. These libs are working only with image data, without dom elements (canvas and image).

About the canvas, size restriction see this post

Solution 3

I think this method is best way for this solution.

function base64Resize(sourceBase64, scale , callBack) {

    const _scale = scale;
    var img = document.createElement('img');
    img.setAttribute("src", sourceBase64);

    img.onload = () => {
        var canvas = document.createElement('canvas');
        canvas.width = img.width * _scale;
        canvas.height = img.height * _scale;

        var ctx = canvas.getContext("2d");
        var cw = canvas.width;
        var ch = canvas.height;
        var maxW = img.width * _scale;
        var maxH = img.height * _scale;

        var iw = img.width;
        var ih = img.height;
        var scl = Math.min((maxW / iw), (maxH / ih));
        var iwScaled = iw * scl;
        var ihScaled = ih * scl;
        canvas.width = iwScaled;
        canvas.height = ihScaled;
        ctx.drawImage(img, 0, 0, iwScaled, ihScaled);
        const newBase64 = canvas.toDataURL("image/jpeg", scl);

        callBack(newBase64);
    }
}

Important point is that you should use img.onload event.

Share:
100,435
rilar
Author by

rilar

Coder by day, hacker by night.

Updated on July 05, 2022

Comments

  • rilar
    rilar almost 2 years

    I need a way to resize pictures in JavaScript without using a HTML element.

    My mobile HTML app captures photos and then converts them to base64 strings. Thereafter I need to resize them before they are sent to the API in order to save storage space.

    I'm looking for a different and more suitable way for resizing than using a canvas element, is there a way?

  • funguy
    funguy about 7 years
    You are not using "datas" nowhere.
  • Pierrick Martellière
    Pierrick Martellière about 7 years
    "img.src = datas;" in the bottom of the snippet.
  • carpiediem
    carpiediem over 5 years
    Thank you for actually answering the question. I'm not sure why people vote-up answers that rely on canvas, despite the requirement to avoid it being the key part of the question... This seems to be the only solution for node.js.
  • Giox
    Giox about 5 years
    I can't understand the code, what should I put in "Use and treat your Data URI here"?
  • ILIAS M.  DOLAPO
    ILIAS M. DOLAPO over 4 years
    Your code works very well, you can easily display. by : var newImage = document.createElement('img'); newImage.src = dataURI; document.getElementById("imgTest").innerHTML = newImage.outerHTML; this makes tit to display to the browser
  • Chique
    Chique almost 3 years
    The question says "without using canvas".
  • Michael Fever
    Michael Fever over 2 years
    i'm not familliar with using a callBack - how would I use this?
  • Prid
    Prid over 2 years
    @MichaelFever: when you call the function, you can attach a function as the 3rd parameter which is called once the resizing is done. This can also be an inline anonymous function, e.g. base64Resize("data:image/png;base64,iVBO...", 0.5, function(resizedImage){ // resizedImage is variable for the resized base64 image });. But it's not necessary. If you don't want it, remove callBack from parameter list and remove the callBack(newBase64); line :)
  • Pencilcheck
    Pencilcheck about 2 years
    pica also uses canvas, this is not the asked solution though
  • Alex Nikulin
    Alex Nikulin about 2 years
    @Pencilcheck, not it uses bitmap.. but you can create bitmap without canvas, by jpg-js, and then put this bitmap into pica.