Open In App

Create an Image Resizer and Compressor Using React

In this tutorial, we'll create an image resizer and compressor application using React. 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 image resize and compressor using React. The application allows user to upload an image, resize it based on specific dimensions or percentages, adjust the compression quality, and download the compressed image.

Preview of Final Output: Let us have a look at how the final application will look like:

resizer

Prerequisites:

Approach to Create an Image Resizer and Compressor in React:

Steps to Create Image Resizer and Compressor in React:

Step 1: let's create a new React project using Create React App.

npx create-react-app <<Project_Name>>

Step 2: Change to the project directory.

cd <<Project_Name>>

Step 3: Create a folder called components in src directory and create the following files inside it ImageResizer.js and ImageResizer.css .

Project Structure:

rl

The updated dependencies in package.json will look like this:

"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
},

Example: Below is an example of creating a image resizer and compressor using react.

/* App.css */

.container {
    text-align: center;
    margin-top: 50px;
}

.title {
    margin-bottom: 20px;
}

.image-upload {
    margin-bottom: 20px;
}

.upload-label {
    cursor: pointer;
    padding: 10px 20px;
    border: 2px solid #ccc;
    border-radius: 5px;
    display: inline-block;
}

.output {
    margin-top: 20px;
}

.preview-label {
    margin-bottom: 10px;
}

#preview {
    max-width: 100%;
    max-height: 300px;
    margin-bottom: 10px;
}

.controls {
    margin-top: 20px;
}

.control-group {
    margin-bottom: 10px;
}

label {
    margin-right: 5px;
}

input[type='number'] {
    width: 60px;
    padding: 5px;
    border: 1px solid #ccc;
    border-radius: 3px;
}

.quality-group {
    margin-bottom: 20px;
}

input[type='range'] {
    width: 200px;
    margin-left: 5px;
}

.quality-value {
    margin-left: 5px;
}

#resizeButton {
    padding: 10px 20px;
    background-color: #007bff;
    border: none;
    border-radius: 5px;
    color: #fff;
    cursor: pointer;
}

#resizeButton:hover {
    background-color: #0056b3;
}

.download-button {
    display: inline-block;
    padding: 10px 20px;
    background-color: #28a745;
    border: none;
    border-radius: 5px;
    color: #fff;
    cursor: pointer;
    text-decoration: none;
    margin-top: 20px;
}

.download-button:hover {
    background-color: #218838;
}
/* Imageresizer.css */

.container {
    text-align: center;
    margin-top: 50px;
    max-width: 600px;
    margin-left: auto;
    margin-right: auto;
    padding: 20px;
    border: 1px solid #ccc;
    border-radius: 5px;
    background-color: #c5b9b9;
}

.title {
    margin-bottom: 20px;
}

.image-upload {
    margin-bottom: 20px;
}

.upload-label {
    cursor: pointer;
    padding: 10px 20px;
    border: 2px solid #007bff;
    border-radius: 5px;
    display: inline-block;
    color: #007bff;
    font-weight: bold;
}

.output {
    margin-top: 20px;
}

.preview-label {
    margin-bottom: 10px;
}

#preview {
    max-width: 100%;
    max-height: 300px;
    margin-bottom: 10px;
}

.controls {
    margin-top: 20px;
}

.control-group {
    margin-bottom: 10px;
}

label {
    margin-right: 5px;
    font-weight: bold;
}

input[type='number'] {
    width: 60px;
    padding: 5px;
    border: 1px solid #ccc;
    border-radius: 3px;
}

.quality-group {
    margin-bottom: 20px;
}

input[type='range'] {
    width: 200px;
    margin-left: 5px;
}

.quality-value {
    margin-left: 5px;
    font-weight: bold;
}

#resizeButton {
    padding: 10px 20px;
    background-color: #28a745;
    border: none;
    border-radius: 5px;
    color: #fff;
    cursor: pointer;
}

#resizeButton:hover {
    background-color: #218838;
}

.download-button {
    display: inline-block;
    padding: 10px 20px;
    background-color: #007bff;
    border: none;
    border-radius: 5px;
    color: #fff;
    cursor: pointer;
    text-decoration: none;
    margin-top: 20px;
}

.download-button:hover {
    background-color: #0056b3;
}
// App.js

import React from "react";
import "./App.css";
import ImageResizer from "./components/ImageResizer.js";

function App() {
    return (
        <div className="App">
            <ImageResizer />
        </div>
    );
}

export default App;

// Imageresizer.js

import React, {
    useState
} from 'react';
import './ImageResizer.css';

const ImageResizer = () => {
    const [image, setImage] = useState(null);
    const [width, setWidth] = useState('');
    const [height, setHeight] = useState('');
    const [percentage, setPercentage] = useState('');
    const [quality, setQuality] = useState(80);

    const handleImageChange = (e) => {
        const file = e.target.files[0];
        if (file) {
            const reader = new FileReader();
            reader.onload = () => {
                setImage(reader.result);
            };
            reader.readAsDataURL(file);
        }
    };

    const handleResizeAndCompress = () => {
        const img = document.createElement('img');
        img.onload = () => {
            const canvas = document.createElement('canvas');
            const ctx = canvas.getContext('2d');

            let targetWidth, targetHeight;

            if (width && height) {
                targetWidth = parseInt(width, 10);
                targetHeight = parseInt(height, 10);
            } else if (percentage) {
                targetWidth = (parseInt(
                    percentage, 10) * img.width) / 100;
                targetHeight = (parseInt(
                    percentage, 10) * img.height) / 100;
            } else {
                targetWidth = img.width;
                targetHeight = img.height;
            }

            canvas.width = targetWidth;
            canvas.height = targetHeight;

            ctx.drawImage(img, 0, 0, targetWidth, targetHeight);

            const compressedDataUrl = canvas.toDataURL(
                'image/jpeg', quality / 100);
            setImage(compressedDataUrl);
        };
        img.src = image;
    };

    const handleDownload = () => {
        const link = document.createElement('a');
        link.href = image;
        link.download = 'compressed_image.jpg';
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
    };

    return (
        <div className="container">
            <h1 className="title">
                Image Resizer and Compressor
            </h1>

            <div className="image-upload">
                <label htmlFor="imageInput"
                    className="upload-label">
                    <i className="fas fa-cloud-upload-alt"></i>
                    Upload an Image
                </label>
                <input
                    type="file"
                    id="imageInput"
                    accept="image/*"
                    onChange={handleImageChange}
                />
            </div>

            {image && (
                <div id="action-form">
                    <div className="output">
                        <h2 className="preview-label">Preview:</h2>
                        <img id="preview" src={image} alt="Preview" />
                        <p id="image-dimensions" style={{
                            marginTop: '10px'
                        }}>
                        </p>
                    </div>

                    <div className="controls">
                        <div className="control-group">
                            <label htmlFor="resizeWidth">Width:</label>
                            <input
                                type="number"
                                id="resizeWidth"
                                placeholder="Width"
                                value={width}
                                onChange={(e) => setWidth(e.target.value)}
                            />
                        </div>
                        <div className="control-group">
                            <label htmlFor="resizeHeight">Height:</label>
                            <input
                                type="number"
                                id="resizeHeight"
                                placeholder="Height"
                                value={height}
                                onChange={(e) => setHeight(e.target.value)}
                            />
                        </div>
                        <div className="control-group">
                            <label htmlFor="resizePercentage">
                                Percentage:
                            </label>
                            <input
                                type="number"
                                id="resizePercentage"
                                placeholder="Percentage"
                                value={percentage}
                                onChange={(e) => setPercentage(e.target.value)}
                            />
                        </div>
                        <div className="control-group quality-group">
                            <label htmlFor="quality">Quality:</label>
                            <input
                                type="range"
                                id="quality"
                                min="1"
                                max="100"
                                value={quality}
                                onChange={(e) => setQuality(e.target.value)}
                            />
                            <span id="quality-value" className="quality-value">
                                {quality}
                            </span>
                        </div>
                        <button id="resizeButton"
                            onClick={handleResizeAndCompress}>
                            Resize & Compress
                        </button>
                        {image && (
                            <a
                                id="downloadButton"
                                className="download-button"
                                href={image}
                                download="compressed_image.jpg"
                                onClick={handleDownload}
                            >
                                Download Compressed Image
                            </a>
                        )}
                    </div>
                </div>
            )}
        </div>
    );
};

export default ImageResizer;

Start your application using the following command.

npm start

Output: Open web-browser and type the following URL http://localhost:3000/.

bandicam2024-03-0619-13-15-956-ezgifcom-video-to-gif-converter

Article Tags :