Skip to content

HelixCipher/media-compressor

Repository files navigation

Media Compressor

Project Project_Demonstration_GIF.gif

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.

Features

  • 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.

How It Works

Compression Algorithm

The app uses an intelligent compression strategy:

  1. Tests Maximum Quality (100): First checks what the image size would be at maximum quality.

  2. Fits Under Target: If max quality ≤ target, returns it immediately at quality 100.

  3. Finds Optimal Quality: Otherwise, searches for the highest quality that fits under target.

  4. Scales if Necessary: For very small targets, gradually reduces image dimensions.

Important Limitations

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.

Project Structure

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.

Quick Start

Using Docker

# Build and start the container
docker-compose up --build

# Access the app
open http://localhost:5000

Manual Setup

# Install dependencies
pip3 install -r requirements.txt

# Run the Flask app
python3 app.py

# Access the app
open http://localhost:5000

Usage Guide

Image Compression

  1. Upload an Image: Drag & drop or click Browse to select an image.

  2. Set Target Size: Use the slider to set desired output size (20KB - 5000KB).

  3. Adjust Quality: Set JPEG quality (10-100).

  4. Click "Resize & Download": The app processes and downloads automatically.

  5. Check Feedback: The status shows:

    • Actual file size achieved

    • Quality level used (1-100)

    • Whether target was achieved, exceeded, or maxed out

Video Compression

  1. Click "Video" tab: Switch to video compression mode.

  2. Upload a Video: Drag & drop or click Browse to select a video.

  3. Set Target Size: Use the slider to set desired output size (1MB - 500MB).

  4. Choose Resolution: Select output resolution (Original, 1080p, 720p, 480p, 360p, 240p).

  5. Choose Format: Select output format (MP4, WebM, MKV, AVI, MOV).

  6. Choose Codec: Select video codec (H.264, HEVC, VP9).

  7. Adjust Audio: Set audio bitrate (32-320 kbps).

  8. Click "Compress & Download": The app processes and downloads the compressed video.

Understanding Results

Target Achieved

Output is within 50% of target size at maximum quality

Example:

  • Target: 200KB

  • Actual: 192KB at quality 80

  • Status: "Target achieved"

Max Quality Reached

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)"

Over Target

Could not compress enough to meet target

Example:

  • Target: 50KB

  • Actual: 60KB (20% over target)

  • Status: "20% over target"

Technical Details

Backend (app.py)

Image Compression Function:

def compress_image_to_target(img, target_kb, start_quality=90, min_quality=5)

Image Algorithm:

  1. Converts image to RGB

  2. Tests quality 100 first

  3. If fits: returns immediately

  4. If too large: searches for best fitting quality (100 → 5)

  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:

  1. Uses FFmpeg for video processing

  2. Two-pass VBR encoding for accurate target size

  3. Supports resolution scaling

  4. CRF-based compression for targets below minimum achievable size

Frontend (index.html)

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

Configuration

Environment Variables

None required - all settings are UI-controlled

File Upload Limits

  • Maximum file size: No limit

  • Supported image formats: PNG, JPG, JPEG

  • Supported video formats: MP4, WebM, MKV, AVI, MOV

Troubleshooting

"Image too small for target"

Your uploaded image compresses too efficiently. Upload a larger/higher resolution image.

Theme not switching

Clear browser cache and reload. The theme is stored in localStorage.

Download not starting

Check browser's download settings. Some browsers block automatic downloads.

Development

Adding New Features

The codebase is modular:

  • app.py: Add new compression strategies in compress_image_to_target()

  • index.html: Modify applyTheme() for UI changes

  • Add new sliders/controls by updating the form and JavaScript event listeners

Testing

# 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}')
"

Architecture Decisions

  1. Server-side processing: More reliable than client-side canvas compression.

  2. Maximum quality priority: Always tries quality 100 first, then reduces only if needed.

  3. Single container: Simpler deployment, no CORS issues.

  4. Progressive JPEG: Better perceived loading performance.

  5. Manual theme switching: Tailwind CDN doesn't support dark: variants without config


License & Attribution

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.

Attribution requirements

Any reuse, redistribution, or derivative work must include:

  1. The creator’s name: HelixCipher
  2. A link to the original repository:
    https://github.com/HelixCipher/media-compressor
  3. An indication of whether changes were made
  4. A reference to the license (CC BY 4.0)

Example Attribution

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/


Disclaimer

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.

About

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.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors