Open In App

Create an Image Resizer and Compressor Using React

Last Updated : 12 Mar, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

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:

  • Functionality: Upload, resize, and compress images.
  • State Management: Utilizes React’s useState for managing image properties.
  • Image Handling: FileReader for image upload; img element for manipulation.
  • Resizing and Compression: Adjusts dimensions and quality of the image.
  • UI Components: Displays controls and preview for image manipulation.
  • Download Functionality: Provides a link for downloading the compressed image.
  • App.js: This component is responsible, for rendering the layout of the application.
  • ImageResizer.js : ImageResizer.js is a React component responsible for handling image resizing and compression within the image resizer application. This component allows users to upload an image, specify dimensions (width, height, or percentage), adjust compression quality, and download the compressed image.
  • ImageResizer.css : ImageResizer.css contains the styles for the image resizer application, ensuring a visually appealing and user-friendly interface.

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.

CSS
/* 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;
}
CSS
/* 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;
}
Javascript
// 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;

Javascript
// 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



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads