Python Flask HEIC to JPG Convert - Full Code
Python Flask HEIC to JPG Convert - Full Code

Python Flask HEIC to JPG Convert – Full Code

Introduction

Modern smartphones, especially Apple devices, save photos in the HEIC (High Efficiency Image Container) format. While HEIC offers excellent image compression while retaining quality, many platforms, websites, and software tools still lack full support for it.

As a result, converting HEIC to JPG becomes essential in various scenarios. JPG is universally supported and provides better compatibility across browsers, websites, and social platforms.

Whether you’re a Python developer, tech enthusiast, or small business owner working on web applications, learning how to convert HEIC to JPG using Python Flask can be a game-changer. It simplifies workflows and expands the usability of your applications.

In this guide, we’ll walk you through the process step by step, ensuring seamless image compatibility for your projects.

Why Python Flask HEIC to JPG?

HEIC (High Efficiency Image Container) is now the standard format used by iPhones and modern Apple devices to store photos. It’s highly efficient — offering smaller file sizes without compromising on quality.
However, the biggest drawback is compatibility. Many web platforms, desktop applications, and non-Apple devices struggle to support HEIC files without third-party tools or updates.

That’s why converting HEIC to the more universal JPG format is often necessary. JPG is widely accepted across browsers, design tools, social platforms, and operating systems.
Whether you’re uploading product images, sharing photos via email, or building a web-based application — JPG just works.

Why Use Python and Flask?

Python is powerful, beginner-friendly, and supported by robust libraries like Pillow and pillow-heif, which make image processing simple.

On top of that, Flask allows developers to wrap this functionality into a lightweight web application. With Flask, users can upload HEIC files, convert them to JPG, preview the result, and download the final image — all from their browser.

As a result, this isn’t just a practical utility; it’s also a hands-on learning opportunity for developers working with real-world web apps.

Benefits of Converting HEIC to JPG with Python Flask

Despite its efficiency, the HEIC format lacks universal compatibility. That’s where Python Flask HEIC to JPG conversion comes in — offering:

  • Cross-platform usability – JPG works on all devices, browsers, and design tools.
  • Faster sharing – JPG is lightweight and supported by social media and cloud services.
  • Web optimization – JPG remains the industry standard for web images and digital content.

If you’re building an app or website that handles user-generated content, integrating an HEIC-to-JPG converter can drastically improve accessibility and user satisfaction.

Key Features of Our Converter App

1. Upload HEIC Files Easily
Our web app offers a user-friendly interface where users can quickly upload .heic files from their device. The file input supports drag-and-drop or traditional browsing. It also validates file types to ensure only supported HEIC images are selected.

2. One-Click Conversion to JPG
Once uploaded, the image is converted to .jpg format with a single click. Behind the scenes, we use the pillow-heif and Pillow libraries to handle high-efficiency image decoding and format transformation. The conversion is seamless and fast.

3. Live Preview Before Download
After conversion, the app generates a live preview of the JPG image directly in the browser. This helps users visually verify the result before downloading — saving time and preventing mistakes.

4. Adjustable Image Quality
Users can control the output quality (e.g., 70%, 90%, or full quality). This is especially helpful when balancing file size with visual clarity, such as when preparing images for web uploads.

5. Instant Download Option
After previewing the result, users can download the converted image instantly using the provided download button. The file retains its original name (with .jpg extension), making it easy to identify and organize.

Our app ensures a smooth 4-step workflow:
Import → Convert → Preview → Download

Prerequisites for Python Flask HEIC to JPG

Before you begin building the converter app, make sure the following prerequisites are in place:

✅ Python 3.x installed
You should have Python 3.x installed on your system. You can download it from the official Python website.

✅ Basic knowledge of Flask and HTML
Understanding Flask's route handling and simple HTML form structures will help you follow along easily.

✅ Install required libraries
Use the following pip command to install all the necessary Python packages:

Required Python Libraries:

To build the HEIC to JPG converter using Flask, install the following libraries:

  • Flask – a lightweight web framework to build the web interface.
  • Pillow – Python Imaging Library for image processing.
  • pillow-heif – plugin for Pillow to support HEIC/HEIF image formats.
pip install flask pillow pillow-heif

Step 1: Set Up Your Flask Project

Create a new folder and organize it like this:

heic_converter/
│
├── app.py
├── templates/
│   └── index.html
└── static/
    ├── styles.css
    └── preview/

heic_converter : Main Project Folder you can anything to use as per your like name.

app.py : is Python program file to use all python code in this file.
templates : Create folder in projrect folder to use HTML file.
index.html : file create in (templates) folder.
static : This is styles file folder to create in main project folder.
styles.css : This is HTML style file to use of decorate to your HTML Layout UI (Framework) look as you like.
preview : To Run program and Look.

This structure helps separate the backend, frontend, and static assets clearly.

Step 2: Write Flask Backend Code

Let’s build the heart of our app in app.py. This handles uploads, conversion, preview, and downloads.

from flask import Flask, render_template, request, send_file, jsonify, url_for
import os
from werkzeug.utils import secure_filename
from pillow_heif import register_heif_opener
from PIL import Image
import io

app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = 'uploads'
app.config['CONVERTED_FOLDER'] = 'converted'

# Ensure folders exist
os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True)
os.makedirs(app.config['CONVERTED_FOLDER'], exist_ok=True)

# Enable HEIC reading for PIL
register_heif_opener()

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/convert', methods=['POST'])
def convert():
    if 'file' not in request.files:
        return jsonify({'error': 'No file uploaded'}), 400

    file = request.files['file']
    quality = int(request.form.get('quality', 80))

    if file.filename == '':
        return jsonify({'error': 'No file selected'}), 400

    filename = secure_filename(file.filename)
    if not filename.lower().endswith('.heic'):
        return jsonify({'error': 'Invalid file type. Please upload a HEIC file.'}), 400

    upload_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
    file.save(upload_path)

    try:
        with Image.open(upload_path) as img:
            rgb_image = img.convert('RGB')
            output_filename = os.path.splitext(filename)[0] + '.jpg'
            output_path = os.path.join(app.config['CONVERTED_FOLDER'], output_filename)
            rgb_image.save(output_path, 'JPEG', quality=quality)

        # Generate preview URL
        preview_url = url_for('static', filename='preview/' + output_filename)

        # Copy converted image to static/preview folder for browser preview
        preview_folder = os.path.join('static', 'preview')
        os.makedirs(preview_folder, exist_ok=True)
        rgb_image.save(os.path.join(preview_folder, output_filename), 'JPEG', quality=quality)

        download_url = url_for('download_file', filename=output_filename)

        return jsonify({'preview_url': preview_url, 'download_url': download_url})

    except Exception as e:
        return jsonify({'error': f'Conversion failed: {str(e)}'}), 500

@app.route('/download/<filename>')
def download_file(filename):
    file_path = os.path.join(app.config['CONVERTED_FOLDER'], filename)
    return send_file(file_path, as_attachment=True)

if __name__ == '__main__':
    app.run(debug=True)

Step 3: Create the Web Interface (HTML + CSS) to use for Python Flask HEIC to JPG

Our index.html makes it easy for users to upload and convert HEIC files.

templates/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>HEIC to JPG Converter</title>
    <link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}">
</head>
<body>
<div class="container">
    <h1>HEIC to JPG Converter</h1>
    <div class="img-in">
    <input type="file" id="fileInput" accept=".heic">
    </div>
    <div class="controls">
        <label for="qualitySlider">Quality: <span id="qualityValue">80</span>%</label>
        <input type="range" id="qualitySlider" min="10" max="100" value="80">
    </div>
    <div class="btn-1">
    <button id="convertButton" disabled>Convert Image</button>
    </div>

    <div id="previewContainer" style="display:none;">
        <h3>Converted Image Preview</h3>
        <img id="previewImage" src="#" alt="Preview Image">
        <br><br>
        <a id="downloadButton" href="#" class="download-btn" download>Download JPG</a>
    </div>
</div>

<script>
const fileInput = document.getElementById('fileInput');
const convertButton = document.getElementById('convertButton');
const qualitySlider = document.getElementById('qualitySlider');
const qualityValue = document.getElementById('qualityValue');

const previewContainer = document.getElementById('previewContainer');
const previewImage = document.getElementById('previewImage');
const downloadButton = document.getElementById('downloadButton');

let selectedFile = null;

qualitySlider.addEventListener('input', () => {
    qualityValue.textContent = qualitySlider.value;
});

fileInput.addEventListener('change', function() {
    const file = this.files[0];
    if (file) {
        const fileName = file.name.toLowerCase();
        const validExtensions = ['.heic'];
        const isValid = validExtensions.some(ext => fileName.endsWith(ext));

        if (isValid) {
            selectedFile = file;
            convertButton.disabled = false;
            previewContainer.style.display = 'none';
        } else {
            alert('Please select a valid HEIC file.');
            resetAll();
        }
    }
});

convertButton.addEventListener('click', function() {
    if (!selectedFile) {
        alert('No file selected.');
        return;
    }

    const quality = qualitySlider.value;
    const formData = new FormData();
    formData.append('file', selectedFile);
    formData.append('quality', quality);

    convertButton.disabled = true;
    convertButton.textContent = 'Converting...';

    fetch('/convert', {
        method: 'POST',
        body: formData
    })
    .then(res => res.json())
    .then(data => {
        convertButton.disabled = false;
        convertButton.textContent = 'Convert Image';

        if (data.error) {
            alert('Error: ' + data.error);
        } else {
            previewImage.src = data.preview_url + '?t=' + new Date().getTime(); // prevent cache
            downloadButton.href = data.download_url;
            previewContainer.style.display = 'block';
        }
    })
    .catch(err => {
        alert('Conversion failed.');
        convertButton.disabled = false;
        convertButton.textContent = 'Convert Image';
    });
});

function resetAll() {
    fileInput.value = '';
    selectedFile = null;
    convertButton.disabled = true;
    previewContainer.style.display = 'none';
}
</script>
</body>
</html>

static/styles.css

body {
    font-family: Arial, sans-serif;
    text-align: center;
    padding: 30px;
    background: #f4f4f4;
}

h1 {
    font-family:sans-serif;
}

.container {
    background: white;
    padding: 20px 120px 80px 120px;
    border-radius: 10px;
    display: inline-block;
}

.img-in {
    padding: 20px 0;

}

img {
    max-width: 400px;
    margin-top: 15px;
    border: 1px solid #ccc;
}

.controls {
    margin: 15px 0;

}

.btn-1 {
    padding-top: 10px;
}

button, .download-btn {
    padding: 10px 20px;
    font-size: 16px;
    text-decoration: none;
    background-color: #007BFF;
    color: white;
    border: none;
    border-radius: 5px;
}

button:disabled {
    background-color: #999;
}

.download-btn {
    display: inline-block;
}

Conclusion

Converting HEIC to JPG is no longer a complex task — especially with Python and Flask at your fingertips. By combining the power of pillow and pillow-heif, you can easily build a lightweight, browser-based converter that’s fast, user-friendly, and highly compatible.

Whether you’re a developer creating tools for your users or someone who regularly deals with HEIC images, this project offers a practical solution and a great learning opportunity.

With just a few lines of code, you can enable image upload, live preview, format conversion, and instant downloads — all inside a clean Flask app. As a result, you’ll not only solve a real-world problem but also strengthen your skills in Python web development.

This Python Flask HEIC to JPG converter is a great project for those exploring more Flask web apps or diving deeper into image processing with Python.