Open In App

Create a Resize and Compress Images in HTML CSS & JavaScript

Last Updated : 12 Oct, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

While using the GeeksforGeeks Write Portal to write articles, we need to upload the images. As we need to resize the image as per GeeksforGeeks’s requirement, we search for different tools and websites on the internet to resize and compress the image. But, as a web developer, we can create our own image resize and compressor using HTML, CSS, and JavaScript.

This project contains HTML, CSS, and JavaScript files. The HTML files consist of the overall structure of our application; the CSS file contains the layout and styling of the application. The JavaScript file has the complete functionality to handle the images, resize and compress them, and also download them.

Preview

Screenshot-2023-10-09-at-12-28-44-Image-Resizer-and-Compressor-min

Prerequisites

Approach:

For resizing and compressing the image, we will first prompt the user to load the image in the application. Once the user uploads the image, a basic preview of the image is displayed to the user, and then the user needs to be given the desired ratio of width and height, as well as the provision to set the quality of the image by dynamically adjusting the quality bar. When the user does the customization, the user needs to press the button. After pressing the button, the image gets resized and compressed; simultaneously,  the preview gets updated, and the download button is pressed. The user can download the image by clicking on this button.

Example: This example describes the basic implementation for resizing and compressing the image in HTML, CSS and JavaScript lanaguage.

HTML




<!DOCTYPE html>
<html lang="en">
  
<head>
    <meta charset="UTF-8">
    <meta name="viewport" 
          content="width=device-width, 
                    initial-scale=1.0">
    <title>
        Image Resizer and Compressor
    </title>
    <link rel="stylesheet" href="styles.css">
</head>
  
<body>
    <div class="container">
        <h1 class="title">
            Image Resizer and Compressor
        </h1>
  
        <div class="image-upload">
            <label for="imageInput" 
                   class="upload-label">
                <i class="fas fa-cloud-upload-alt">
                </i> Upload an Image
            </label>
            <input type="file" 
                   id="imageInput" 
                   accept="image/*">
        </div>
  
        <div id="action-form" 
             style="display: none;">
            <div class="output">
                <h2 class="preview-label">
                    Preview:
                </h2>
                <img id="preview" alt="Preview">
                <p id="image-dimensions" 
                   style="margin-top: 10px;">
                </p>
            </div>
  
            <div class="controls">
                <div class="control-group">
                    <label for="resizeUnit">
                        Unit:
                    </label>
                    <select id="resizeUnit">
                        <option value="pixels">
                            Pixels
                        </option>
                        <option value="percentage">
                            Percentage
                        </option>
                    </select>
                </div>
  
                <div class="control-group" 
                     id="pixel-dimensions">
                    <label for="resizeWidth">
                        Width:
                    </label>
                    <input type="number" 
                           id="resizeWidth" 
                           placeholder="Width">
                    <span>px</span>
                </div>
  
                <div class="control-group" 
                     id="percentage-dimensions" 
                     style="display: none;">
                    <label for="resizePercentage">
                        Percent:
                    </label>
                    <input type="number" 
                           id="resizePercentage" 
                           placeholder="Percentage" 
                           min="1" 
                           max="100">
                    <span>%</span>
                </div>
  
                <div class="control-group" 
                     id="pixel-height-dimensions">
                    <label for="resizeHeight">
                        Height:
                    </label>
                    <input type="number" 
                           id="resizeHeight" 
                           placeholder="Height">
                    <span>px</span>
                </div>
  
                <div class="control-group quality-group">
                    <label for="quality">
                        Quality:
                    </label>
                    <input type="range" 
                           id="quality" 
                           min="1" 
                           max="100" 
                           value="80">
                    <span id="quality-value" 
                          class="quality-value">
                      80
                      </span>
                </div>
  
                <button id="resizeButton">
                    Resize & Compress
                </button>
                <a id="downloadButton" 
                   class="download-button" 
                   style="display: none">
                    Download Compressed Image
                </a>
  
            </div>
        </div>
    </div>
    <script src="script.js"></script>
</body>
  
</html>


CSS




* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}
body {
    font-family: "Segoe UI", Tahoma,
        Geneva, Verdana, sans-serif;
    background-color: #eefd97;
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
    margin: 0;
}
.container {
    background-color: #eeeeee;
    padding: 50px;
    border-radius: 15px;
    box-shadow: 0 5px 15px
        rgba(0, 0, 0, 0.1);
    max-width: 550px;
    width: 100%;
}
.title {
    background-color: #a0fd94;
    font-size: 32px;
    text-transform: uppercase;
    margin-bottom: 20px;
}
.image-upload {
    text-align: center;
}
.upload-label {
    background-color: #007bff;
    color: #fff;
    padding: 15px 20px;
    border-radius: 8px;
    cursor: pointer;
    font-size: 18px;
    margin-bottom: 20px;
    transition: background-color 0.3s;
    box-shadow: 0 2px 5px
        rgba(0, 0, 0, 0.2);
    display: flex;
    align-items: center;
    justify-content: center;
}
.upload-label:hover {
    background-color: #0056b3;
    transform: scale(1.05);
}
.upload-label i {
    margin-right: 8px;
    font-size: 24px;
}
input[type="file"] {
    display: none;
}
.output {
    margin-top: 30px;
    text-align: center;
}
.preview-label {
    color: #333;
    font-size: 24px;
    margin-bottom: 10px;
}
img {
    max-width: 100%;
    height: auto;
    display: block;
    margin: 20px auto;
    border: 2px solid #007bff;
    border-radius: 8px;
    box-shadow: 0 4px 10px
        rgba(0, 0, 0, 0.2);
    transition: transform 0.3s;
}
img:hover {
    transform: scale(1.05);
}
.controls {
    margin-top: 30px;
}
.control-group {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 20px;
}
label {
    font-size: 20px;
    font-weight: bold;
    color: #333;
}
input[type="number"],
input[type="range"],
select {
    width: 70%;
    padding: 10px;
    border: 2px solid #ccc;
    border-radius: 8px;
    font-size: 18px;
    transition: border-color 0.3s;
}
input[type="number"]:focus,
input[type="range"]:focus,
select:focus {
    border-color: #007bff;
}
.quality-group {
    position: relative;
}
input[type="range"] {
    width: 100%;
    -webkit-appearance: none;
    height: 10px;
    border-radius: 8px;
    background: #ccc;
    outline: none;
    transition: background 0.3s;
}
input[type="range"]::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: #007bff;
    cursor: pointer;
    box-shadow: 0 2px 5px
        rgba(0, 0, 0, 0.2);
    position: relative;
    z-index: 2;
}
.quality-group:hover
    input[type="range"] {
    background: #0056b3;
}
.quality-value {
    position: absolute;
    top: -1px;
    left: calc(106% - 25px);
    color: #ff0000;
    font-size: 18px;
    background-color: rgb(
        136,
        223,
        169
    );
    padding: 4px 10px;
    border-radius: 6px;
    box-shadow: 0 px 5px
        rgba(0, 0, 0, 0.2);
}
button {
    background-color: #007bff;
    color: #fff;
    border: none;
    padding: 15px 30px;
    cursor: pointer;
    font-size: 20px;
    border-radius: 8px;
    transition: background-color 0.3s,
        transform 0.3s;
    box-shadow: 0 4px 10px
        rgba(0, 0, 0, 0.2);
    outline: none;
}
button:hover {
    background-color: #0056b3;
    transform: scale(1.05);
}
.download-button {
    background-color: #0056b3;
    color: #fff;
    border: none;
    padding: 15px 30px;
    cursor: pointer;
    font-size: 20px;
    border-radius: 8px;
    text-decoration: none;
    display: inline-block;
    margin-top: 20px;
    transition: background-color 0.3s,
        transform 0.3s;
    box-shadow: 0 4px 10px
        rgba(0, 0, 0, 0.2);
}
.download-button:hover {
    background-color: #004180;
    transform: scale(1.05);
}
#resizeUnit {
    width: 60%;
    font-size: 18px;
    margin-right: 100px;
}
#pixel-dimensions,
#percentage-dimensions,
#pixel-height-dimensions {
    display: flex;
    align-items: center;
}
#pixel-dimensions span,
#percentage-dimensions span,
#pixel-height-dimensions span {
    margin-left: 10px;
    font-size: 18px;
    color: #333;
}


Javascript




document.addEventListener(
    "DOMContentLoaded",
    () => {
        let imgInput =
            document.getElementById("imageInput");
        let imgShow =
            document.getElementById("preview");
        let rUnit =
            document.getElementById("resizeUnit");
        let rwidth =
            document.getElementById("resizeWidth");
        let rpercent =
            document.getElementById("resizePercentage");
        let dimensions =
            document.getElementById("pixel-dimensions");
        let perdimension =
            document.getElementById("percentage-dimensions");
        let pxheight =
            document.getElementById(
                "pixel-height-dimensions");
        let imgQuality =
            document.getElementById("quality");
        let qualValue =
            document.getElementById("quality-value");
        let resizeBtn =
            document.getElementById("resizeButton");
        let downloadBtn =
            document.getElementById("downloadButton");
        let imgDimensions =
            document.getElementById("image-dimensions");
        let action =
            document.getElementById("action-form");
        let imageResized = false;
  
        let updateQualVal = () => {
            qualValue.innerText =
                imgQuality.value;};
        updateQualVal();
        imgQuality.addEventListener("input",
            updateQualVal);
        imgInput.addEventListener(
            "change",
            () => {
                let imgFile =imgInput.files[0];
                let readFile = new FileReader();
                readFile.onload = (
                    e
                ) => {
                    imgShow.src = e.target.result;
                    showActionForm();
                    showImageDim(
                        imgFile
                    );};
                readFile.readAsDataURL(
                    imgFile
                );
            });
        const showActionForm = () => {
            action.style.display = "block";};
        const showImageDim = (
            imgFile
        ) => {
            const image = new Image();
            image.onload = () => {
                const width = image.width;
                const height = image.height;
                imgDimensions.innerText = 
                    `Image Dimensions: 
                     ${width} x ${height} 
                     pixels`;};
            image.src =
                URL.createObjectURL(
                    imgFile
                );};
        const dimFeildsShow = () => {
            if (
                rUnit.value === "pixels"
            ) {
                dimensions.style.display =
                    "block";
                pxheight.style.display =
                    "block";
                perdimension.style.display =
                    "none";
            } else {
                dimensions.style.display =
                    "none";
                pxheight.style.display =
                    "none";
                perdimension.style.display =
                    "block";
            }};
        rUnit.addEventListener(
            "change",
            dimFeildsShow);
        const updateDimensions = () => {
            if (
                rUnit.value === "pixels"
            ) {
                imgDimensions.innerText = 
                    `Image Dimensions: 
                     ${rwidth.value} x 
                     ${resizeHeight.value} 
                     pixels`;
            } else {
                const percentage =
                    parseInt(
                        rpercent.value
                    );
                if (
                    !isNaN(percentage)
                ) {
                    const width =
                        (imgShow.width *
                            percentage) / 100;
                    const height =
                        (imgShow.height *
                            percentage) / 100;
                    imgDimensions.innerText = 
                    `Image Dimensions: 
                     ${Math.round(width)} x 
                     ${Math.round(height)} 
                     pixels`;
                }}};
        resizeBtn.addEventListener(
            "click",
            () => {
                if (imageResized) {
                    return;
                }
                let wid;
                let height;
                if (
                    rUnit.value ===
                    "percentage"
                ) {
                    const percentage =
                        parseInt(
                            rpercent.value
                        );
                    if (
                        isNaN(
                            percentage
                        ) ||
                        percentage <
                        1 ||
                        percentage > 100
                    ) {
                        alert(
                            `Please enter a valid 
                             percentage (1-100).`
                        );
                        return;}
                    wid =
                        (imgShow.width *
                            percentage) / 100;
                    height =
                        (imgShow.height *
                            percentage) / 100;
                    rwidth.value = wid;
                    resizeHeight.value = height;
                } else {
                    wid = parseInt(
                        rwidth.value
                    );
                    height = parseInt(
                        resizeHeight.value
                    );
                }
                let imageQuality =
                    parseInt(
                        imgQuality.value) / 100;
                let canvas =
                    document.createElement(
                        "canvas");
                let ctx =
                    canvas.getContext(
                        "2d");
                let imageObj =
                    new Image();
                imageObj.onload =
                    () => {
                        canvas.width =
                            wid;
                        canvas.height =
                            height;
                        ctx.drawImage(
                            imageObj,
                            0, 0, wid, height);
                        let resizedDataUrl =
                            canvas.toDataURL(
                                "image/jpeg",
                                imageQuality
                            );
                        let resizedImage =
                            new Image();
                        resizedImage.src =
                            resizedDataUrl;
                        imgShow.src =
                            resizedDataUrl;
                        downloadBtn.style.display =
                            "inline-block";
                        downloadBtn.href =
                            resizedDataUrl;
                        downloadBtn.download =
                            "compressed-image.jpg";
                        updateDimensions();
                        imageResized = true;
                    };
                imageObj.src =
                    imgShow.src;
            });});


Output:

Compress



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads