Skip to main content
All right — what are we building? In this lesson you’ll build the Super Image Optimizer: a small web app that accepts an uploaded image, lets the user choose a compression level, compresses the image server-side, and returns the optimized image while showing original + new file sizes and the percentage reduction. Core capabilities
  • Single-image optimization via a web UI
  • Adjustable compression quality (1–100)
  • A Flask REST API that performs image processing with OpenCV and validates output with Pillow
  • A React frontend for file selection, quality control, upload flow, and results display
Quick start — clone and create a Python virtual environment
Example shell prompt from the project folder:
What the backend does (high level)
  • Accepts a multipart/form-data POST with a file field and optional quality form field
  • Validates the uploaded bytes and image type
  • Decodes the image into OpenCV, handles alpha / grayscale safely, and encodes to JPEG with the requested quality
  • Verifies the resulting JPEG with Pillow to catch encoding issues
  • Returns the compressed JPEG as binary data (image/jpeg)
Below is the self-contained Flask Blueprint used for the upload endpoint. It validates the uploaded file, decodes into OpenCV, compresses to JPEG using the requested quality, verifies with Pillow, and returns the image bytes.
API contract (endpoint summary) Allowed image types (server-side validation) A brief frontend overview
  • The React app provides a file picker, a slider/input for quality (e.g., 77), and an “Optimize Image” button.
  • On submit it sends a multipart/form-data POST to /upload.
  • When the response arrives the frontend displays the optimized image along with statistics: original size, optimized size, and percent reduction (calculated client-side based on byte lengths).
  • Use React hooks to manage file state, upload progress, and display results.
Example snippet from the React app:
User experience example
  • Select a photo from your machine.
  • Set the slider to the desired quality (e.g., 87).
  • Click “Optimize Image”.
  • The UI updates to show original size, optimized size, and the percentage reduction.
Example curl request (client-side usage)
A desktop screenshot of a web app titled "Image Optimizer" showing an upload field, a quality slider set to 77%, and an "Optimize Image" button with an "Original Image" cartoon portrait below. The app is displayed in a browser tab inside a code editor window.
How it works (step-by-step)
  1. Frontend collects the file + quality and posts to the Flask /upload endpoint.
  2. Flask reads the raw bytes, uses imghdr.what to validate the image type.
  3. Bytes are converted to a NumPy buffer and decoded with OpenCV (cv2.imdecode).
  4. If the image includes alpha, convert BGRA -> BGR; handle grayscale safely.
  5. Re-encode to JPEG via cv2.imencode with cv2.IMWRITE_JPEG_QUALITY set to the requested value.
  6. Wrap the encoded bytes in BytesIO and verify that Pillow can open/verify the image (optional safety check).
  7. Return the image to the client as image/jpeg. The frontend measures byte sizes and computes percentage savings.
Helpful notes and cautions
Tip: Keep quality between 1 (most compression, lower quality) and 100 (least compression, near-original quality). The Flask code clamps out-of-range values to this range automatically.
Warning: In production, enforce file-size limits and authentication, sanitize filenames, and consider scanning uploads for malicious content. Large images can consume significant memory while OpenCV decodes them.
Where to find the full project
A dark-mode GitHub repository page for a project called "Super-Image-Optimizer," showing folders, files, and the README. The sidebar notes it's a web-based image optimizer with language and release info.
Links and references Thank you for following along — the article walks through backend and frontend implementation step-by-step so you can run and iterate on this optimizer locally or extend it for batch processing and production deployment.

Watch Video