Skip to content

report_images

Image optimization for the web report.

Prepares comparison images generated by :mod:src.comparison for efficient delivery via the static HTML report. Two pipelines are provided:

  • Lossless integer-scaled — for fragment comparison grids where pixel fidelity is critical. Generates 1×, 2× and 3× variants using nearest-neighbour resampling so that each original source pixel maps to exactly 1×1, 2×2 or 3×3 device pixels respectively.

  • Lossy multi-format — for distortion maps, annotated originals and other visualisation images where minor compression artefacts are acceptable. Produces AVIF (quality 60, YUV444) and WebP lossy variants at multiple widths for <picture>/srcset delivery.

Both pipelines write optimised files into the report output tree and return metadata used by the Jinja templates to emit correct <img> or <picture> markup.

  • LOSSY_TARGET_WIDTHS
  • SVG_PRECISION
  • AVIF_QUALITY
  • WEBP_QUALITY

optimise_svg(source: 'Path', dest: 'Path', precision: 'int' = 1) → Path

Optimise an SVG file with SVGO and write the result to dest.

Runs npx svgo using :data:_SVGO_CONFIG, which enables removeStyleElement on top of the default preset, combined with --multipass and the given floating-point precision.

removeStyleElement strips the embedded <style> block that Matplotlib writes into every SVG. Those rules are redundantly inlined on individual elements, so their removal is lossless and typically yields the largest share of size reduction.

If SVGO is unavailable or fails the source file is copied verbatim and a warning is printed so that report generation is never blocked.

Args:

  • source: Path to the original .svg file.
  • dest: Destination path (parent directories are created as needed).
  • precision: Number of digits in the fractional part of numeric values. Lower values yield smaller files at the cost of sub-pixel accuracy — 1 is sufficient for screen rendering.

Returns: Path to the written file (dest).


optimise_lossless(
source: 'Path',
output_dir: 'Path',
report_root: 'Path',
alt: 'str' = ''
) → OptimisedImage

Copy a lossless comparison grid as a single lossless WebP.

Fragment comparison grids use nearest-neighbour zoom with text labels rendered at a matching font size. Down-scaling to 2× or 1× would preserve pixel fidelity of the image fragments but ruin the label text, and lossless WebP compresses the repeating 3×3 pixel blocks so efficiently that the size saving would be negligible. Therefore we serve a single full-resolution variant.

Args:

  • source: Path to the original lossless comparison grid.
  • output_dir: Directory where the variant will be written.
  • report_root: Root of the report output tree (for relative paths).
  • alt: Alt-text for the image.

Returns:

  • :class: OptimisedImage with a single lossless WebP variant.

optimise_lossy(
source: 'Path',
output_dir: 'Path',
report_root: 'Path',
alt: 'str' = '',
target_widths: 'list[int] | None' = None
) → OptimisedImage

Create lossy AVIF + WebP variants at multiple widths.

Args:

  • source: Path to the source image (any Pillow-readable format or lossless WebP).
  • output_dir: Directory for the generated variants.
  • report_root: Report output root for computing relative paths.
  • alt: Alt-text for the <img> element.
  • target_widths: Desired widths; defaults to :data:LOSSY_TARGET_WIDTHS.

Returns:

  • :class: OptimisedImage with AVIF and WebP variants.

discover_and_optimise(
analysis_dir: 'Path',
study_id: 'str',
output_dir: 'Path',
report_root: 'Path'
) → StudyComparisonImages

Discover comparison images and create optimised variants.

Scans <analysis_dir>/<study_id>/comparison/ for output files generated by :func:src.comparison.generate_comparison, optimises them for web delivery, and returns structured metadata for template rendering.

The expected directory layout is:

comparison/ <metric>/ # e.g. ssimulacra2/, bits_per_pixel/ comparison_60.webp distortion_map_comparison_60.webp distortion_map_anisotropic.webp original_annotated.webp
For resolution studies:
comparison/ r720/ <metric>/ ... r1080/ <metric>/ ...
**Args:**
- <b>`analysis_dir`</b>: Root analysis directory (e.g. ``data/analysis``).
- <b>`study_id`</b>: Study identifier.
- <b>`output_dir`</b>: Report output directory (e.g. ``data/report``).
- <b>`report_root`</b>: Same as *output_dir* (used for relative path computation).
**Returns:**
- <b>`:class`</b>: `StudyComparisonImages` ready for template rendering.
---
<a href="https://github.com/kadykov/web-image-formats-research/blob/main/src/report_images.py#L620"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>
## <kbd>function</kbd> `srcset_lossless`
```python
srcset_lossless(opt: 'OptimisedImage') → str

Build a srcset attribute value for a lossless :class:OptimisedImage.

Uses width descriptors (<width>w).


picture_html(
opt: 'OptimisedImage',
css_class: 'str' = '',
sizes: 'str' = '',
lightbox: 'bool' = False
) → str

Render a <picture> element for a lossy :class:OptimisedImage.

Emits <source> elements for AVIF and WebP, with a <img> fallback. When lightbox is True the whole element is wrapped in an <a> with data-pswp-* attributes understood by PhotoSwipe 5.


img_srcset_html(
opt: 'OptimisedImage',
css_class: 'str' = '',
sizes: 'str' = '',
lightbox: 'bool' = False
) → str

Render an <img> with srcset for a lossless :class:OptimisedImage.

When lightbox is True the element is wrapped in an <a> with data-pswp-* attributes understood by PhotoSwipe 5.


A single optimised image file.

Attributes:

  • path: Absolute path to the file on disk.
  • rel_path: Path relative to the report output root (for HTML src).
  • width: Pixel width.
  • height: Pixel height.
  • media_type: MIME type (image/webp, image/avif, …).
  • lossless: Whether the variant is losslessly encoded.

__init__(
path: 'Path',
rel_path: 'str',
width: 'int',
height: 'int',
media_type: 'str',
lossless: 'bool' = False
) → None

Collection of variants for a single source image.

Attributes:

  • source_path: Original (unoptimised) file.
  • alt: Alt-text for the <img> element.
  • kind: One of "lossless" or "lossy" indicating the optimisation pipeline used.
  • variants: All generated variants, grouped by MIME type.
  • default: The variant to use as the <img src> fallback.

__init__(
source_path: 'Path',
alt: 'str',
kind: 'str',
variants: 'dict[str, list[ImageVariant]]' = <factory>,
default: 'ImageVariant | None' = None
) → None

All optimised images for one target metric group.

Each set corresponds to one metric subdirectory (e.g. ssimulacra2/ or bits_per_pixel/). Within that directory there is one annotated original and one aggregate distortion map, plus one fragment grid and one distmap grid per target value.

Attributes:

  • strategy: Always "anisotropic" for the current pipeline.
  • resolution: Resolution label (e.g. "r720") or None.
  • target_metric: Target metric name (e.g. "ssimulacra2").
  • original_annotated: The annotated original image.
  • distortion_map: The aggregated distortion map.
  • fragment_grids: Fragment comparison grids (one per target value within the group).
  • distmap_grids: Distortion-map comparison grids (same cardinality as fragment_grids).

__init__(
strategy: 'str',
resolution: 'str | None' = None,
target_metric: 'str | None' = None,
original_annotated: 'OptimisedImage | None' = None,
distortion_map: 'OptimisedImage | None' = None,
fragment_grids: 'list[OptimisedImage]' = <factory>,
distmap_grids: 'list[OptimisedImage]' = <factory>
) → None

All comparison image sets for a study.

Attributes:

  • study_id: Study identifier.
  • sets: Per-strategy (and optionally per-resolution) image sets.

__init__(study_id: 'str', sets: 'list[ComparisonImageSet]' = <factory>) → None