1 of 27

2 of 27

Image Fidelity

Produce high fidelity images without compromising on performance

3 of 27

Majid Ali Khan

I am a software engineer working with 1x Internet from last 9 years and with Drupal roughy 14 years.

4 of 27

Images Dominate the Web

  • Images are the single largest component of page weight
  • On the median desktop page, images account for ~48 % of total bytes transferred

  • First visual impression

  • Yet Drupal ships with a single global quality setting and no AVIF controls

Source: HTTP Archive 2024, desktop median

Typical page weight breakdown

5 of 27

How Normally Drupal Processes Images

★ Covered in this talk

PHP GD

Ships with Drupal core

  • Built into PHP zero extra setup
  • Works everywhere by default
  • Limited format support
  • No WebP quality control (core bug)
  • No AVIF encoding options

★ Covered in this talk

ImageMagick

Contrib module + server binary

  • Full JPEG / WebP / AVIF control
  • Superior resize quality
  • Metadata stripping
  • Requires server-level install
  • Most used deliberate upgrade

CDN

e.g. Cloudinary, imgix, Fastly

  • Offload image processing
  • Format negotiation (AVIF→WebP→JPEG)
  • Usually precofigured
  • No Drupal-side processing
  • Out of scope for this talk

GD is Drupal's default — it runs on every site that hasn't deliberately switched. ImageMagick requires installing a contrib module and a server binary, but gives you real control over image quality.

6 of 27

PHP GD — Drupal's default image toolkit

1

Drupal's out-of-the-box image toolkit — works with zero configuration

Drupal core selects GD automatically unless you explicitly switch. Every image style resize, crop, and scale operation runs through GD without any server setup, making it universally available.

2

Processes images in memory using pixel-level operations — Slow and eats a lot of RAM

GD reads the source image into a PHP resource, applies transformations (resize, crop, rotate, convert) pixel by pixel, then writes the output file. It supports JPEG, PNG, GIF, and WebP as input and output formats.

Simple but limited — quality and format control are constrained

GD offers no per-format quality tuning beyond a single integer, no AVIF support, no metadata handling, and uses a fixed resampling algorithm. It is reliable for basic use but leaves advanced image optimisation out of reach.

3

7 of 27

"Quality 80" is not "Quality 80"

JPEG, WebP and AVIF use completely different internal scales — the same number means a completely different thing

JPEG

WebP

AVIF

Algorithm

DCT — rigid 8×8 px blocks

VP8 predictive coding(single video frame)

AV1 dynamic blocks(4 px – 128 px)

Internal scale

0–100 (IJG 1992)

0–100 (Google-mapped)

0–100 → QP 0–63 (translated)

★ Recommended

Q 85

Q 80

Q 60–65

Failure artifact

Blocky & crunchy(8×8 grids visible)

Soft & blurry(watercolour smearing)

Smooth & waxy(over-smoothed gradients)

Size vs JPEG

Baseline

~25% smaller

~50% smaller

⚠ Never use a single global quality for all formats. Q 85 on AVIF produces bloated files — it is equivalent to JPEG Q 95. Use Q85 / Q80 / Q60 for JPEG / WebP / AVIF respectively.

8 of 27

The Core Patch — a proposed fix for GD2

✦ New in patch

Proposed a core patch per-format quality controls for the GD2 core toolkit

  • Renamed global quality → JPEG quality
  • Added WebP quality — independent of JPEG
  • Added Lossless / Lossy radio toggle for WebP output��drupal.org/node/3320689

9 of 27

Seems like the problem is solvedunfortunately, no

1

GD strips colour profile

GD simply dose not care and strips out all the color profile in image.

2

Fixed resampling — always bicubic

No filter choice. For sharp downscales the Mitchell or Lanczos filter is measurably better, but GD hardcodes bicubic with no override.

3

Memory explosion on large images

A 10 MB JPEG becomes 200 MB+ in RAM as raw RGBA pixels. Large image styles regularly crash PHP processes on memory-limited hosts.

4

No metadata

EXIF orientation, ICC colour profiles, copyright data — GD handles none selectively. You get everything or nothing.

Two big problems with it — Soft & Dull images

10 of 27

Enter ImageMagick — the professional's toolkit

200+ format support

AVIF, WebP, HEIF, TIFF, RAW, HDR — every modern format GD cannot touch.

Per-format quality & encoding

Separate quality targets per codec. JPEG Q 85, WebP Q 80, AVIF Q 60 — each optimal.

Resampling filter selection

Mitchell, Lanczos, Sinc — choose the right filter for each resize operation.

Metadata & colour-profile control

Strip, preserve, or selectively copy EXIF/ICC data. Correct colour rendering across devices.

Drupal contrib module

drupal.org/project/imagemagick wraps the CLI with a clean admin UI. Drop-in replacement for GD.

11 of 27

But the current ImageMagick UI has gaps

Single global quality — same problem as GD

One field for all formats. JPEG and AVIF at the same integer produces either bloated AVIF or degraded JPEG.

AVIF: no encoder controls in the UI

ImageMagick supports AVIF via libheif, but there was no UI to set encoding speed, bit depth, or chroma subsampling.

WebP: no lossless, method, or sharp-YUV options

Only a quality number. No lossless toggle, no encoding method selector, no sharp-YUV for better chroma reproduction.

No resampling filter selector

The current default varies by operation. No way for site builders to choose a sharper or faster filter.

Arguments field fails silently

Typos, wrong flags, unsupported options — the free-text arguments box gives no feedback. You never know what actually ran.

12 of 27

Patch: Advanced image settings

Resampling filter

Controls the algorithm used when resizing. Mitchell is the best general-purpose choice. Lanczos is sharper for downscales. Defaults to ImageMagick's built-in per-operation choice.

Rendering intent

Controls how out-of-gamut colours are mapped during ICC colour-profile conversion. Perceptual is recommended for photographs; Relative colorimetric for logos.

Strip metadata

Removes EXIF, IPTC, and XMP metadata from output files. Reduces file size and prevents leaking GPS coordinates or camera info in public images.

13 of 27

Patch: JPEG quality & chroma

JPEG quality

Separate quality field for JPEG output (0–100). Values 80–85 are typical for high-quality web images. Overrides the fallback quality.

Fallback quality

A global fallback for formats not covered by per-format tabs (PNG, GIF, etc.). JPEG, WebP, and AVIF tabs override this.

Chroma subsampling

Eyes resolve brightness sharply but colour poorly — storing colour at half resolution saves ~30 % with no visible loss.

drupal.org/project/imagemagick/issues/3585578

14 of 27

Patch: WebP encoding settings

WebP quality (0–100)

Independent quality for WebP output. Q 80 is the recommended sweet spot — ~25% smaller than JPEG Q 85 at equivalent visual quality.

Encoding method (0–6)

Trade encoding time for file size. Method 4 (default) is a good balance; method 6 squeezes out extra bytes at the cost of slower saves.

Use sharp YUV

Improves chroma accuracy on high-contrast edges. Recommended ON for photos; has a small encoding cost.

Auto filter

Lets the WebP encoder automatically choose optimal filtering per block. Slightly slower but can improve quality at same file size.

Image hint

Hints the encoder about image type (photo, picture, graph). Allows format-specific optimisation paths.

15 of 27

Patch: AVIF encoding settings

AVIF quality (0–100)

AVIF Q 60 is roughly equivalent to JPEG Q 85 — ~50% smaller file. The scale is inverted internally (higher = lower QP), so Q 85 would bloat the file.

Encoding speed (0–10)

Lower = better compression but slower. Speed 5 (libheif default) is a balanced starting point. Speed 0 is best quality for offline processing.

Bit depth

8-bit for standard web photos; 10/12-bit for HDR/wide-gamut sources. 10-bit is the only option ImageMagick never chooses automatically — the only way to produce a true 10-bit AVIF. Smart guard: for 10/12-bit configs the patch reads source depth via identify; if the source does not carry sufficient depth the flag is skipped entirely, letting ImageMagick encode at the native source depth. 8-bit is always applied unconditionally — the only way to force downscale from a high-depth source.

Chroma subsampling

4:2:0 (default) is recommended for most photos — smallest files. 4:4:4 for graphics with text or sharp colour transitions.

Uses heic: coder prefix — heif: is silently ignored by ImageMagick 7

16 of 27

Patch: Resampling filter

34 filters — server-probed

The patch queries ImageMagick at runtime and populates the dropdown from what is actually installed on the server.

Old UI: argument field

Without the patch, users had to type the filter name into a raw text field — no hint of what was available.

MagicKernelSharp2021 (default)

Modern sharpening kernel; best general-purpose choice. Great detail retention without ringing artefacts.

LanczosSharp

Lanczos with a subtle sharpening bias — the go-to recommendation for photo-heavy sites.

Lanczos

Classic gold-standard downscaling filter; widely trusted and preserves fine detail.

drupal.org/project/imagemagick/issues/3585578

17 of 27

https://qrco.de/bgl3Gz

18 of 27

19 of 27

20 of 27

21 of 27

22 of 27

23 of 27

PHP GD

Image Magic

24 of 27

25 of 27

Key Take-Aways

Use the latest image format where possible

JPEG for universal compatibility — WebP for modern browsers with ~25 % savings — AVIF where you need the best compression and can accept encoding time.

Start with quality source material

Re-encoding cannot recover lost detail. A blurry, over-compressed, or low-resolution source stays that way regardless of settings.

Use proven per-format quality settings

JPEG Q85 · WebP Q80 + SharpYUV · AVIF Q60 speed 5 · Chroma 4:2:0 for all three.

Choose a sharp resampling filter

MagicKernelSharp2021 (default) or LanczosSharp. Avoid the ImageMagick built-in default — it is intentionally soft and typically needs an unsharp mask step.

Strip metadata, keep the ICC profile

Saves bytes on every image without colour shift on wide-gamut displays. Stripping the ICC profile makes colours look wrong on P3/Adobe RGB monitors.

26 of 27

Thank you!

Feel free to reach out:

m.ali@1xinternet.de�majid-a@live.com

www.drupal.org/u/majidali

LinkedIn Profile

27 of 27

Thank you for joining us!