Metadata-Version: 2.4
Name: django-img-optimizer
Version: 2.0.1
Summary: Image optimizer for Django.
Author: Peter Stavrou
License: MIT
Project-URL: Homepage, https://github.com/peterstavrou/django-img-optimizer
Classifier: Development Status :: 4 - Beta
Classifier: Framework :: Django
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: Django>=4.2
Requires-Dist: Pillow>=13.0.0
Dynamic: license-file

# Django Image Optimizer

[![Tests](https://github.com/peterstavrou/django-img-optimizer/actions/workflows/build.yml/badge.svg)](https://github.com/peterstavrou/django-img-optimizer/actions/workflows/build.yml) [![PyPI](https://img.shields.io/pypi/v/django-img-optimizer)](https://pypi.org/project/django-img-optimizer/) [![MIT License](https://img.shields.io/badge/license-MIT-9d9d9d)](https://github.com/peterstavrou/django-img-optimizer/blob/main/LICENSE)

Django Image Optimizer generates AVIF and WebP alternatives for static JPEG and PNG images. It keeps an optimized file only when it is smaller than its source, then the template tag serves AVIF first, WebP second, and the original image as the fallback.

## Requirements

- Python 3.11+
- Django 4.2+
- Pillow 13.0+ with AVIF and WebP support

## Installation

```bash
pip install django-img-optimizer
```

Add the app to `INSTALLED_APPS`:

```python
INSTALLED_APPS = [
    # ...
    'django_img_optimizer',
]
```

## Configuration

Set `OPTIMIZE_IMAGE_ROOT` to the top-level static-image directory. The command searches its subdirectories.

```python
OPTIMIZE_IMAGE_ROOT = PROJECT_DIR / 'static' / 'images'
```

Optional settings:

```python
# Integer from 0 to 100. These defaults provide comparable perceptual quality.
OPTIMIZE_IMAGE_AVIF_QUALITY = 61
OPTIMIZE_IMAGE_WEBP_QUALITY = 80

# Source extensions to convert. Default: ['jpg', 'jpeg', 'png'].
OPTIMIZE_IMAGE_TYPES = ['jpg', 'jpeg', 'png']

# Folder names to exclude, including every descendant folder. Default: [].
OPTIMIZE_IMAGE_EXCLUDED_FOLDERS = ['backup-larger-versions']
```

The command records generated files in `.django-img-optimizer.json` inside `OPTIMIZE_IMAGE_ROOT`. Do not edit or commit this generated file. Existing AVIF and WebP files not recorded in that manifest are never overwritten or deleted.

Source image stems must be unique in the same directory. For example, `logo.jpg` and `logo.png` cannot both be optimized because each would produce `logo.avif` and `logo.webp`.

## Usage

Generate optimized images:

```bash
python manage.py optimize_images
```

Delete only files previously generated by this package:

```bash
python manage.py optimize_images --delete
```

## Django templates

Load the tag and use a static path relative to your static directory:

```django
{% load image_optimizer %}
{% optimized_image loading="lazy" decoding="async" src="images/logo.jpg" alt="Logo" class="img-fluid" %}
```

When both optimized files were generated, it renders:

```html
<picture>
<source srcset="/static/images/logo.avif" type="image/avif">
<source srcset="/static/images/logo.webp" type="image/webp">
<img loading="lazy" decoding="async" src="/static/images/logo.jpg" alt="Logo" class="img-fluid">
</picture>
```

Use `auto` to derive `alt` and `title` values from the filename:

```django
{% optimized_image src="images/logo-auto-attributes.jpg" alt="auto" title="auto" %}
```

This renders `alt="Logo Auto Attributes"` and `title="Logo Auto Attributes"`.

Template variables work as normal:

```django
{% with src="images/"|add:image_name|add:".jpg" %}
    {% optimized_image src=src %}
{% endwith %}
```

Use underscores for hyphenated HTML attributes. The tag converts them safely:

```django
{% optimized_image src="images/logo.jpg" data_bs_toggle="modal" data_bs_target="#exampleModal" %}
```

This renders `data-bs-toggle` and `data-bs-target` on the `<img>` element.

## Author

Created by [Peter Stavrou](https://peterstavrou.com/).
