Guide to Client-Side Image Compression using JavaScript in a Web Browser Environment

117 views

Sure, here's a general approach to compressing an image on the client-side using JavaScript.

Assume you're working on a web browser environment where you have a File Input that allows users to select image files.

HTML - Setup a file input and an img preview element

<input id="file-input" type="file" accept="image/*"/>
<img id="preview" style="max-width: 200px; max-height: 200px;"/>

JavaScript - Compressing the image

const fileInput = document.getElementById('file-input');
const preview = document.getElementById('preview');

fileInput.addEventListener('change', (e) => {
    // read file
    let file = e.target.files[0];
    let reader = new FileReader();

    reader.onloadend = function() {
        // create an image
        let img = new Image();
        img.src = reader.result;
        
        img.onload = function(){
            // create a canvas
            let canvas = document.createElement('canvas');

            // calculate the scaling ratio
            let maxSize = 500;
            let ratio = maxSize/Math.max(img.width, img.height);

            // set the canvas dimensions scaled down
            canvas.width = img.width*ratio;
            canvas.height = img.height*ratio;

            // draw the image scaled down
            canvas.getContext('2d').drawImage(img, 0, 0, canvas.width,canvas.height);

            // get the data URL from the canvas
            let newDataUrl = canvas.toDataURL('image/jpeg', 0.7); // 0.7 corresponds to 70% quality

            // show the image preview
            preview.src = newDataUrl;
        }
    }
    reader.readAsDataURL(file);
});

In this example, we're taking the file input and adding an event listener so that when a user selects a file, it creates a new FileReader object and reads the data as a data URL. Then, we create a Image object and assign its source to the FileReader's result. When the image has loaded, we create a canvas, resize the image with respect to its aspect ratio, draw the scaled image on to the canvas, and get a new data URL from the scaled image with a specified quality factor (70%).

Please note that JavaScript image compression using the canvas API technically just changes the height and width of the image and the quality factor: it does not apply advanced compression techniques. For serious use-cases, consider using a JavaScript library specifically designed for image manipulation (e.g., "Pica", "Compress.js", or "sharp" in a Node.js runtime), or sending the image to a server and relying on server-side compression if heavier processing isn't an issue.

Finally, remember that client-side manipulation will not affect the actual image file the user has on their device. Any changes you apply will be to the in-memory image object in your application. If you want to enable downloading of the compressed image by your users, you would need to add saving functionality in JavaScript.