drupal/image_scale_fill · version 1.1.0
Fixed-size image derivatives without cropping
Image Scale and Fill Background adds one effect to Drupal’s image style system. It scales a source image to fit a configured canvas without cropping or distorting it, then fills the remaining area with a background derived from the image itself.
Requirements. Drupal 10.3 or newer, and the GD image
toolkit. Under ImageMagick the effect returns without modifying the image, while still
reporting the configured dimensions to Drupal — so the rendered
<img> carries dimensions the file does not have. Raster sources only:
GD cannot read SVG, and Drupal image styles do not apply to SVG files.
What the effect does
The effect runs when a derivative is first generated. The result is written beside the source’s stream wrapper — a public source produces a public derivative, served as a static file thereafter; a private source produces a private one, served through Drupal. Either way the processing cost is incurred once per derivative rather than per request. Saving an image style discards its existing derivatives, which are regenerated on the next request for each one.
It reports the configured canvas back to Drupal as the output size, which means the rendered
<img> carries width and height attributes that are
identical for every image in a listing.
The effect never crops the image it places on the canvas. The Scaled background type does take a centre-cropped, cover-scaled copy of the source, but that copy sits behind the intact image. For art-directed cropping, where an editor selects the region to keep, use Focal Point or Image Widget Crop. Format conversion is a separate effect chained after this one in the same image style.
Where this is used
The effect applies wherever a layout requires images of one fixed size, the source images arrive at proportions the site does not control, and cropping is not acceptable.
- Listing and teaser grids
- Article indexes, related-content rails and category listings, where derivatives of uneven height break card alignment and push captions out of register.
- Social and open-graph images
- An
og:imagemust be 1200×630 in the file itself; the consumer is a scraper that does not process the site’s stylesheets. - Logo, partner and sponsor listings
- Marks span a wide range of proportions and are usually transparent PNGs. The effect produces a uniform tile and supplies the background the source does not contain.
- Syndication surfaces
- Newsletters, RSS enclosures and feeds consumed by third parties, where the dimensions declared in the file are the only dimensions available.
- Wire, archive and user-supplied imagery
- Content whose composition is not known in advance, where an automated centre crop may remove the subject.
- Responsive image styles
- Because the output size is exactly the configured canvas, a set of styles at 400×225,
800×450 and 1600×900 produces correct width descriptors and a constant aspect ratio
across the whole
srcset.
Where the stored dimensions do not matter — the image is only ever rendered
inside the site’s own stylesheets — object-fit: contain on a fixed-size
element achieves the same visual result with no derivative, no storage and no regeneration.
Section 08 sets out the cases it does not cover.
Output dimensions compared with core image effects
Editorial image sources arrive at dimensions and aspect ratios the receiving site does not
control. The five sources below range from 9.8:1 to 1:1.5, and one is smaller than the target
canvas. Each grid applies a single image style at 800×450 and is laid out
as a CSS grid with img { width: 100% }.
canvas 800×450 · this section concerns output dimensions; background treatments are shown at full size in section 05















| Effect | Output size | Aspect ratio | Content |
|---|---|---|---|
| Scale | varies | preserved | preserved |
| Resize | exact | not preserved | preserved |
| Scale and Crop | exact | preserved | cropped |
| Scale and fill background | exact | preserved | preserved |
Upscaling. In 1.1.0 the effect always scales to fit,
including when the source is smaller than the canvas — the 150×212 book cover above
is enlarged. Core’s Scale effect has an upscale setting for this; this effect
does not. Use a separate style for sources that must not be enlarged, or
open an issue.
Transparent sources and irregular proportions
The six logo files below span 4.23:1 to 1:1.38 — a narrower spread than the photographs in section 03, but concentrated at the extremes rather than distributed across them. All six are transparent PNGs, which contain no background content from which a fill can be derived. This listing uses a square 640×640 canvas: in a 16:9 canvas the 4.23:1 wordmark would fill 58% of the frame against 76% in a square, so the square shows more of what the effect does.
canvas 640×640 · sources rasterised from SVG, since image styles do not process SVG files


















SVG sources. Logo files are commonly SVG, which GD cannot read and Drupal image styles do not process. Rasterise on upload, restrict the field to raster formats, or handle SVG separately with SVG Image. The marks on this page were rasterised to PNG before processing.
Background treatments
The background is derived from the source image rather than configured as a colour. The available combinations are a repeated copy of the image, a cover-scaled copy that is blurred or darkened, and the image’s dominant colour as a flat field or a gradient.
canvas 800×450 · the control below changes the source behind all five results · the first three are derived from a copy of the image, the last two from a single measured colour
Tiled
Blurred
Darkened
Dominant colour
Dominant gradientScarlet macaw
Background type × background style, as the configuration form presents them. A sixth combination, tiled with the coloured overlay, is not shown: its mean per-channel difference from scaled-with-overlay measured 7.17 of 255, because the overlay obscures the repetition that distinguishes a tiled background.
Macaw parrot (Unsplash).jpg by Andrew Pons, CC0 · Zellige loose tile shapes.jpg by Jadcooper, CC BY-SA 4.0
Selecting a treatment. Blurred suits photographs. Dominant colour is the least expensive option and produces the most uniform grid. Tiled is appropriate for pattern and texture sources; repetition is apparent on other subjects. Darkened retains some structure from the source while keeping overlaid text legible.
Background choice moves file size by well under a factor of two: across the sources shown the per-option means ran 40–50 KB per WebP derivative at 800×450, with individual files between 25 and 63 KB.
Fill selection for transparent sources
A transparent source contains no background content from which to derive a fill, and a blurred copy of a logo reproduces the logo rather than producing a background. One setting decides what happens, with four values: three of them detect a transparent source and give it a flat filled background, while the fourth skips the detection entirely and applies the configured background type as if the source were a photograph. Two marks are shown below, one drawn in dark ink and one in white. Each row begins with the transparent source displayed over a checkerboard.
canvas 640×640
Sourcetransparent PNG
Do nothingbackground type is applied
Automaticdark ink, light fill
Fixed colour#F2EFE8
From the imagetint of the markDark ink. All four options produce a legible result, so the choice is stylistic rather than functional.
Sourcetransparent PNG
Do nothingbackground type is applied
Automaticlight ink, dark fill
Fixed colour#F2EFE8
From the imageshade of the markWhite ink. Only Automatic produces a legible result. The fixed colour is the same in both rows.
| Option | Behaviour | Applicable when |
|---|---|---|
Do nothing none | The configured background type is applied to the logo as it would be to a photograph, producing a black canvas with a blurred copy of the mark behind it, or under dominant colour the mark’s own colour | Sources are never transparent |
Automatic auto | A light or dark fill, selected per image from the proportion of ink that is light | Source artwork is not controlled by the site |
Fixed colour fixed | One configured colour for every source | Source artwork is known and consistent |
From the image from_image | The mark’s mean ink colour, mixed 85% toward white or black | A uniform white background is not acceptable |
How Automatic decides. It measures the proportion of the artwork’s ink
whose WCAG relative luminance exceeds 0.5, and selects the dark fill when that proportion exceeds
70%. The luminance threshold is a high bar: mid-grey #808080 sits at approximately
0.22 and counts as dark. Automatic and Fixed produce identical output on dark-ink sources only
when the fixed colour equals the configured light colour; with the fixed colour set to a page
background, as above, they differ. Added in
issue #3618813.
Detection threshold. A source is treated as transparent when 5% or more of sampled pixels carry any transparency at all, antialiased edges included. Sampling is roughly 60 points per axis rather than every pixel. Across the thirteen sources shown on this page, the seven transparent logos measured 28.6% to 76.5% and the six photographs measured a flat 0.0%; nothing fell between. For source sets with that separation, one image style can process photographs and logos together.
Overlay transparency and tiling
Overlay transparency sets opacity. Higher values produce a darker result. The overlay colour is fixed at black; the “Colored overlay” label does not indicate a configurable colour.
Transparency 15background at 85% brightness
Transparency 60background at 40%, the default
Transparency 90background at 10%At 100 the overlay is opaque and the background type has no effect on the output.
A tiled background is always combined with a blur or an
overlay. The configuration provides no unmodified option. An unmodified tile requires
the coloured overlay with transparency set to 0, which paints a fully transparent
rectangle.
Tiled, blurredthe default pairing
Tiled, overlay at 0repetition visible
The same on a photographrepetition apparentTiling produces visible repetition, which suits pattern sources.
When CSS object-fit is sufficient
object-fit: contain on a fixed-size element requires no derivatives, storage or
regeneration, and is sufficient wherever the derivative’s stored dimensions do not matter.
It does not cover the following four cases.
A fill derived from each image. CSS can place a flat colour behind a letterboxed image. It cannot blur that image or calculate its dominant colour.
Cropping. object-fit: cover discards the same content as Scale
and Crop, at render time rather than at derivative generation.
Consumers that do not process CSS. An og:image must be
1200×630 in the file itself. The same applies to newsletters, RSS enclosures and any
surface rendered outside the site’s own stylesheets.
Declared dimensions. Every derivative matches the configured canvas, so the
effect reports one size to Drupal and every rendered <img> carries identical
width and height attributes. Sources of varying proportion do not. The
same property makes a responsive image style produce a constant aspect ratio across its
srcset.
Installation and configuration
composer require drupal/image_scale_fill:^1.1
drush en image_scale_fill
drush updatedb
Add Scale and fill background to an image style at
/admin/config/media/image-styles. Place it last in the style:
anything after it operates on the canvas this effect has drawn. Three decisions determine the
remaining settings.
Transparent sources
If any source is a transparent logo, set Images with a transparent background to Automatic and set its light colour to the page background colour. If no source is transparent, the setting has no effect.
Fill derivation
Derived from the image: Background type: Scaled, Background style: Blurred. Neutral: Background type: Dominant color. Pattern artwork: Tiled with the overlay at 0.
Generation volume
For bulk regeneration, prefer dominant colour, or retain the blur and reduce Resize ratio. See section 11.
Upgrading an existing site. The database update sets every image style that already uses this effect to Do nothing, so the images those styles produce do not change. The update re-saves each affected style, which discards its generated derivatives; each is rebuilt on the next request for it. The Automatic default applies only to effects added afterwards. Sites that deploy configuration from files should re-export after running the update; a style left un-exported is re-saved on every configuration import, which discards its derivatives each time.
| Setting | Default | Range | Effect |
|---|---|---|---|
| Width, Height | — | 1–10000 each; the form additionally caps the product at 40 megapixels | The output canvas. The form rejects both; the configuration schema constrains each side only, not the product. Configuration arriving through an unvalidated import is reduced at runtime and logged. A 40-megapixel canvas requires roughly 160 MB for the canvas alone, before the decoded source, so PHP’s memory limit binds well before the cap |
| Background type | Scaled | Tiled · Scaled · Dominant color | The content the fill is derived from |
| Background style | Blurred | Blurred · Colored overlay | Applies to Tiled and Scaled only, and is ignored for Dominant color. The overlay colour is fixed at black |
| Blur radius | 9 | 1–50 | Blur extent and cost. 3 to 50 measured 741 ms to 3095 ms at 1200×630 |
| Blur sigma | 6 | 0.1–50 | The form rejects a sigma above the blur radius. An imported value above the radius is reduced silently at runtime, without a log entry |
| Resize ratio | 0.3 | 0.1–1 | Canvas reduction applied before blurring, and the largest single cost factor: 0.1 to 1.0 measured 555 ms to 5533 ms at 1200×630 |
| Overlay transparency | 60 | 0–100 | Opacity. Higher values are darker; at 100 the background type has no effect |
| Dominant style | Single color | Single color · Gradient | The gradient end colour is each channel of the dominant colour reduced by 50 and clamped at 0, so a near-black dominant colour produces little or no ramp |
| Gradient direction | Vertical | Vertical · Horizontal | Gradient axis |
| Images with a transparent background | Automatic for new effects; Do nothing for effects that predate the update | Do nothing · Automatic · Fixed color · From the image | See section 06 |
| Light / dark / fixed colour | #FFFFFF / #000000 / #FFFFFF | #RRGGBB only | The light colour is applied behind dark artwork and is the one to match to the page background. A malformed imported value falls back to white |
Blur work is capped. The blur is bounded at twelve million pixel-coefficient operations, so a large canvas combined with a high radius is reduced to stay within the budget and the reduction is logged. Worst-case cost is therefore bounded whatever an editor configures, but resize ratio and blur radius do not always apply literally at large canvas sizes.
Exported image styles
Configuration read back from a site with these styles saved, validated against the
image.style.* schema and its constraints. Save each block under the filename shown in
the configuration sync directory. The UUIDs need only be unique within the destination site; keep
them, or replace both the map key and the uuid value with one new value — they
must match.
Article river and section fronts image.style.isf_teaser_card.yml
uuid: 1847cea3-391c-4a90-8c5c-92a2ad9811e3
langcode: en
status: true
dependencies:
module:
- image_scale_fill
name: isf_teaser_card
label: 'Teaser 800x450'
effects:
0970fc3e-50eb-43f6-a3b2-d25a6271c1b7:
uuid: 0970fc3e-50eb-43f6-a3b2-d25a6271c1b7
id: scale_and_fill_background
weight: 1
data:
width: 800
height: 450
background_type: scaled
background_style: blurred
background_style_dominant: single_color
radius: 9
sigma: 6.0
resize_ratio: 0.3
gradient_direction: vertical
transparency: 60
transparent_handling: auto
transparent_light_color: '#FFFFFF'
transparent_dark_color: '#1A1A1A'
transparent_color: '#FFFFFF'og:image and Twitter cards image.style.isf_social_card.yml
uuid: 2839306e-be49-4951-8414-43a26f729f97
langcode: en
status: true
dependencies:
module:
- image_scale_fill
name: isf_social_card
label: 'Social card 1200x630'
effects:
496ddd09-75b6-4ac7-b13b-61fe03a9ebf4:
uuid: 496ddd09-75b6-4ac7-b13b-61fe03a9ebf4
id: scale_and_fill_background
weight: 1
data:
width: 1200
height: 630
background_type: scaled
background_style: blurred
background_style_dominant: single_color
radius: 9
sigma: 6.0
resize_ratio: 0.3
gradient_direction: vertical
transparency: 60
transparent_handling: auto
transparent_light_color: '#FFFFFF'
transparent_dark_color: '#1A1A1A'
transparent_color: '#FFFFFF'High-volume archive listings and newsletters image.style.isf_archive_thumb.yml
uuid: fa14868f-027f-4ee5-8a15-e3bb8ad1cc40
langcode: en
status: true
dependencies:
module:
- image_scale_fill
name: isf_archive_thumb
label: 'Archive thumbnail 400x400'
effects:
b0c16190-277b-4ef8-9ee5-afe16e084a2d:
uuid: b0c16190-277b-4ef8-9ee5-afe16e084a2d
id: scale_and_fill_background
weight: 1
data:
width: 400
height: 400
background_type: dominant_color
background_style: blurred
background_style_dominant: single_color
radius: 9
sigma: 6.0
resize_ratio: 0.3
gradient_direction: vertical
transparency: 60
transparent_handling: auto
transparent_light_color: '#FFFFFF'
transparent_dark_color: '#1A1A1A'
transparent_color: '#FFFFFF'Sponsor, partner and event logo walls image.style.isf_partner_tile.yml
uuid: 2ca7bf53-71d3-4af3-9622-e4c0c872af12
langcode: en
status: true
dependencies:
module:
- image_scale_fill
name: isf_partner_tile
label: 'Partner tile 640x640'
effects:
e541f0be-5439-441c-bc9a-a10e80134b13:
uuid: e541f0be-5439-441c-bc9a-a10e80134b13
id: scale_and_fill_background
weight: 1
data:
width: 640
height: 640
background_type: dominant_color
background_style: blurred
background_style_dominant: single_color
radius: 9
sigma: 6.0
resize_ratio: 0.3
gradient_direction: vertical
transparency: 60
transparent_handling: auto
transparent_light_color: '#FFFFFF'
transparent_dark_color: '#1A1A1A'
transparent_color: '#FFFFFF'Derivative generation cost
Absolute timings in this environment — a DDEV container on a development workstation — varied by a factor of two to three between runs of the same measurement. Only the relationships below held steady across three runs, so those are what is quoted. Measure absolute figures against representative sources on the target hardware.
Cost is incurred when derivatives are generated, not per request. Saving an image style discards its derivatives, and each is regenerated on the next request that needs it, so the cost lands on front-end traffic rather than at deployment.
Resize ratio is the largest single factor, and it is consistent. At 1200×630, moving it from 0.1 to 1.0 multiplied the time by 10.0, 10.3 and 10.8 across three runs. It reduces the canvas before blurring, and the blurred result is scaled back up, so a low value is much cheaper and the difference is difficult to see.
Blur radius is the next. Raising it from 3 to 50 multiplied the time by roughly four.
Dominant colour is consistently cheaper than the blur, but the margin depends almost entirely on how expensive the source is to decode: across five sources at a fixed 800×450 canvas the gap ran from under 200 ms to over 600 ms in a single run. If the choice matters at your volume, measure it against your own sources.
Canvas size raises cost sub-linearly. The blur is applied to the canvas rather than the source, but per-derivative decoding and encoding dominate at small canvases: sixteen times the pixels produced between two and four times the time, depending on the run.
The effect writes warnings to the log when it reduces a canvas, clamps a setting or reduces the blur working area. These are worth checking after a bulk import.