A web application that allows users to compress images and videos to target file sizes while maintaining maximum quality. Built with Flask backend and Tailwind CSS frontend, containerized with Docker.
-
Image Compression: Compress images to target file size while maintaining quality.
-
Video Compression: Compress videos to target file size using FFmpeg.
-
Drag & Drop Interface: Easy file upload via drag-and-drop or file browser.
-
Target File Size: Set desired output size (images: 20KB - 5000KB, videos: 1MB - 500MB).
-
Multiple Video Formats: Support for MP4, WebM, MKV, AVI, MOV.
-
Resolution Scaling: Scale videos to 1080p, 720p, 480p, 360p, 240p.
-
Codec Selection: H.264, H.265/HEVC, VP9.
-
Theme Switching: Toggle between light and dark modes.
-
Real-time Feedback: Shows actual vs target size with visual indicators.
-
Tab Interface: Switch between Image and Video modes.
The app uses an intelligent compression strategy:
-
Tests Maximum Quality (100): First checks what the image size would be at maximum quality.
-
Fits Under Target: If max quality ≤ target, returns it immediately at quality 100.
-
Finds Optimal Quality: Otherwise, searches for the highest quality that fits under target.
-
Scales if Necessary: For very small targets, gradually reduces image dimensions.
JPEG files have natural size limits based on image content:
-
A 642×721 photo at quality 100 = ~132KB (maximum possible).
-
A 2279×1222 photo at quality 100 = ~485KB (maximum possible).
-
You cannot make a JPEG larger than its natural maximum at quality 100.
What this means:
-
If you set target to 5000KB but upload a small image, you'll get ~132KB (quality 100).
-
The app shows "Max quality reached (image too small for target)" when this happens.
-
For larger output files, upload higher resolution images.
image-resizer/
├── .gitignore # Git ignore rules
├── ATTRIBUTION.md # Attribution requirements (CC BY 4.0)
├── DISCLAIMER.md # Usage disclaimer and limitations
├── Dockerfile # Docker image configuration
├── LICENSE # CC BY 4.0 License
├── Project_Demonstration_GIF.gif # Demo animation for README
├── README.md # This file
├── app.py # Flask backend with compression logic
├── docker-compose.yml # Docker Compose configuration
├── requirements.txt # Python dependencies
└── templates/
└── index.html # Tailwind CSS frontend with theme switching
File Descriptions:
-
.gitignore- Excludes Python cache files, virtual environments, IDE configs, and generated test files from version control. -
ATTRIBUTION.md- Attribution requirements when reusing or building upon this work (CC BY 4.0). -
DISCLAIMER.md- Usage limitations, liability disclaimer, and important notices. -
Dockerfile- Defines the Python 3.11 container with Flask and Pillow dependencies. -
LICENSE- Creative Commons Attribution 4.0 International (CC BY 4.0) License. -
Project_Demonstration_GIF.gif- Animated demonstration of the application (displayed in README). -
README.md- Project documentation and usage guide. -
app.py- Main Flask application with image compression algorithm. -
docker-compose.yml- Orchestrates the Docker container with volume mounts and port mapping. -
requirements.txt- Lists Flask, Pillow, and gunicorn dependencies. -
templates/index.html- Frontend interface with drag-drop, sliders, and theme switching.
# Build and start the container
docker-compose up --build
# Access the app
open http://localhost:5000# Install dependencies
pip3 install -r requirements.txt
# Run the Flask app
python3 app.py
# Access the app
open http://localhost:5000-
Upload an Image: Drag & drop or click Browse to select an image.
-
Set Target Size: Use the slider to set desired output size (20KB - 5000KB).
-
Adjust Quality: Set JPEG quality (10-100).
-
Click "Resize & Download": The app processes and downloads automatically.
-
Check Feedback: The status shows:
-
Actual file size achieved
-
Quality level used (1-100)
-
Whether target was achieved, exceeded, or maxed out
-
-
Click "Video" tab: Switch to video compression mode.
-
Upload a Video: Drag & drop or click Browse to select a video.
-
Set Target Size: Use the slider to set desired output size (1MB - 500MB).
-
Choose Resolution: Select output resolution (Original, 1080p, 720p, 480p, 360p, 240p).
-
Choose Format: Select output format (MP4, WebM, MKV, AVI, MOV).
-
Choose Codec: Select video codec (H.264, HEVC, VP9).
-
Adjust Audio: Set audio bitrate (32-320 kbps).
-
Click "Compress & Download": The app processes and downloads the compressed video.
Output is within 50% of target size at maximum quality
Example:
-
Target: 200KB
-
Actual: 192KB at quality 80
-
Status: "Target achieved"
Output is at quality 100 but significantly under target (image too small)
Example:
-
Target: 5000KB
-
Actual: 132KB at quality 100
-
Status: "Max quality reached (image too small for target)"
Could not compress enough to meet target
Example:
-
Target: 50KB
-
Actual: 60KB (20% over target)
-
Status: "20% over target"
Image Compression Function:
def compress_image_to_target(img, target_kb, start_quality=90, min_quality=5)Image Algorithm:
-
Converts image to RGB
-
Tests quality 100 first
-
If fits: returns immediately
-
If too large: searches for best fitting quality (100 → 5)
-
If nothing fits: scales down 10% and retries
Video Compression Function:
def compress_video_to_target(input_stream, filename, target_mb, output_format='mp4', resolution=None, codec='h264', audio_bitrate=128)Video Algorithm:
-
Uses FFmpeg for video processing
-
Two-pass VBR encoding for accurate target size
-
Supports resolution scaling
-
CRF-based compression for targets below minimum achievable size
Features:
-
Drag & drop with visual feedback
-
Real-time slider updates
-
Theme toggle (light/dark mode)
-
Size comparison feedback panel
-
File preview before processing
-
Image/Video tab switching
-
Video preview with controls
Theme Classes:
-
Light mode:
bg-white,border-gray-300,text-gray-800 -
Dark mode:
bg-gray-900,border-gray-700,text-gray-100
None required - all settings are UI-controlled
-
Maximum file size: No limit
-
Supported image formats: PNG, JPG, JPEG
-
Supported video formats: MP4, WebM, MKV, AVI, MOV
Your uploaded image compresses too efficiently. Upload a larger/higher resolution image.
Clear browser cache and reload. The theme is stored in localStorage.
Check browser's download settings. Some browsers block automatic downloads.
The codebase is modular:
-
app.py: Add new compression strategies incompress_image_to_target() -
index.html: ModifyapplyTheme()for UI changes -
Add new sliders/controls by updating the form and JavaScript event listeners
# Test compression algorithm directly
python3 -c "
from app import compress_image_to_target
from PIL import Image
img = Image.open('test.jpg')
buf, quality, size = compress_image_to_target(img, 500, 90, 5)
print(f'Result: {size/1024:.1f}KB at quality {quality}')
"-
Server-side processing: More reliable than client-side canvas compression.
-
Maximum quality priority: Always tries quality 100 first, then reduces only if needed.
-
Single container: Simpler deployment, no CORS issues.
-
Progressive JPEG: Better perceived loading performance.
-
Manual theme switching: Tailwind CDN doesn't support
dark:variants without config
This project is licensed under the Creative Commons Attribution 4.0 International (CC BY 4.0) license.
You are free to use, share, copy, modify, and redistribute this material for any purpose (including commercial use), provided that proper attribution is given.
Any reuse, redistribution, or derivative work must include:
- The creator’s name:
HelixCipher - A link to the original repository:
https://github.com/HelixCipher/media-compressor - An indication of whether changes were made
- A reference to the license (CC BY 4.0)
This work is based on Media Compressor by
HelixCipher.
Original source: https://github.com/HelixCipher/media-compressor
Licensed under the Creative Commons Attribution 4.0 International (CC BY 4.0).
You may place this attribution in a README, documentation, credits section, or other visible location appropriate to the medium.
Full license text: https://creativecommons.org/licenses/by/4.0/
This project is provided “as-is”. The author accepts no responsibility for how this material is used. There is no warranty or guarantee that the scripts are safe, secure, or appropriate for any particular purpose. Use at your own risk.
see DISCLAIMER.md for full terms. Use at your own risk.
