Skip to content

Image Sizes

padams edited this page Oct 14, 2026 · 4 revisions

Image Sizes

Sets the quality WordPress saves JPEG and WebP image sizes at, and which registered sizes it makes, on the Image Sizes tab of PhotoPress › Settings. A background job brings existing images up to date after either changes.

The Image Sizes tab
The Image Sizes tab.

Requirements

  • WordPress 6.6 or later.
  • Block and classic themes alike. The tab is in the admin. Nothing is added to the front end.
  • Regenerating existing images needs each image's original file on the server. With WP Offload Media set to remove files from the server, existing images cannot be regenerated. See Offload Media and CDN.
  • The ImageMagick limits apply only where the PHP Imagick extension is loaded.

Settings

Open PhotoPress › Settings › Image Sizes.

Quality
The quality slider.

Sizes
Every registered size, with a switch for each.

Control What it does Default
JPEG and WebP quality The quality, out of 100, that WordPress saves JPEG and WebP sizes at. The slider runs from 50 to 100. Other formats keep WordPress's quality. 92
Sizes table, On switch One row per registered size: its name, its largest dimensions (and whether it is cropped), and a switch. A size registered by a theme or plugin is marked "(theme or plugin)". A size switched off is not made for new uploads. All on
Save Saves the settings. Existing images are not changed.
Save and regenerate N affected images Saves, asks for confirmation, then starts the regenerate job for the images the new settings affect. Shown only when at least one image is affected.

Under the table, one line states how many images lack a size that is on, or were made at another quality ("12 of 340 images lack sizes turned on here, or were made at another quality."). It appears only while the screen has no unsaved change.

The number in Save and regenerate is recounted for the settings on screen, 400 ms after each change.

Save vs Save and regenerate

  • Save applies the settings to images uploaded from then on.
  • Save and regenerate also starts the images.regenerate job. A progress panel, Regenerating image sizes, shows the count done, failures, errors and a Cancel button. You can leave the page. The job keeps running. See Background Jobs.
  • If a regenerate job is already running, the settings are saved and the job is not started again. The images the running job has still to do get the new settings. Run Save and regenerate again after it finishes for the rest.

How it works

Quality

PhotoPress filters wp_editor_set_quality for image/jpeg and image/webp only (code). A stored value outside 1–100 leaves WordPress's quality in place.

Each image made at a known quality has the post meta _photopress_quality. A new upload gets it when WordPress makes its sizes (markUpToDate). An image without it is taken to have been made at the quality saved the first time PhotoPress needed the value. That value is stored in the option photopress_images_assumed_quality (code).

Sizes on and off

PhotoPress removes switched-off sizes from intermediate_image_sizes_advanced (code). The sizes stay registered. A theme that asks by name for a size an image lacks gets the nearest size the image has.

Switching a size off does not delete it from existing images. They keep its files and metadata, including when the job remakes every size.

What the regenerate job does to each image

For each image the job decides what it needs (work):

Condition Work done
JPEG or WebP made at a quality other than the setting, or metadata without width and height Every size made again from the original upload.
A size that is on is missing, and the image (or, for a -scaled image, its original) is large enough for it Only the missing sizes are made.
Neither Nothing. The image counts as done.

A change to WordPress's big image threshold does not count as work. It applies the next time an image's sizes are made from its original.

Missing sizes only. PhotoPress calls wp_update_image_subsizes() with wp_get_missing_image_subsizes filtered to the sizes that are on (code). WordPress saves the metadata after each size, so a failure midway keeps the sizes made so far.

Every size. PhotoPress calls wp_generate_attachment_metadata() on the original (wp_get_original_image_path()). The save is all or nothing (code):

  • While WordPress works, PhotoPress short-circuits update_post_metadata and add_post_metadata for this image's _wp_attached_file, _wp_attachment_metadata and _photopress_quality. The stored file and metadata stay as they were.
  • update_attached_file records where WordPress points the image (the original, or a new -scaled copy). image_make_intermediate_size records each file made.
  • On success, sizes the image had that are now off are kept if their files exist, the attached file is updated, and the metadata and _photopress_quality are saved once. The legacy meta _photopress_sizes_signature is deleted.
  • On a failure or exception, files made under names the image did not have are deleted. The image keeps its old files and metadata. A size made again under its old name has already overwritten the old file.

With WP Offload Media active, its upload is held until the finished metadata is saved, so the set is uploaded once (code).

When the job finishes, PhotoPress fires photopress_image_sizes_regenerated. Each image whose every size was made again is announced with photopress_image_files_rewritten. With WP Offload Media serving a CloudFront domain, those images are cleared from CloudFront when the job ends, done or cancelled. See Offload Media and CDN.

ImageMagick limits

PhotoPress hooks wp_image_editors, which WordPress applies before it opens any image to edit: uploads, file replacements, the image editor and the job (code). It sets ImageMagick's own limits for the PHP process (code):

Limit Value When
Memory 256 MB Always
Memory map 512 MB Always
Threads 1 In the regenerate job only

Past these limits ImageMagick uses disk, in wp-content/uploads/photopress-tmp. PhotoPress creates that folder with an .htaccess containing Require all denied and an empty index.html (code). PHP's memory_limit does not count ImageMagick's memory.

WordPress integration

Hook Type Code Purpose
wp_editor_set_quality filter images.php#L55 JPEG and WebP quality.
intermediate_image_sizes_advanced filter images.php#L56 Removes switched-off sizes.
wp_generate_attachment_metadata filter images.php#L58 Records _photopress_quality on upload (context create).
wp_image_editors filter images.php#L59 Sets ImageMagick limits. Returns the editors unchanged.
wp_get_missing_image_subsizes filter images.php#L479 During the job only: missing sizes limited to those on.
update_post_metadata, add_post_metadata filter images.php#L525 During a full remake only: holds back saves of the image's file, metadata and quality.
update_attached_file, image_make_intermediate_size filter images.php#L527 During a full remake only: tracks the file WordPress points to and each file made.
rest_api_init action images.php#L57 Registers the routes below.

Core functions relied on: wp_get_registered_image_subsizes(), wp_update_image_subsizes(), wp_generate_attachment_metadata(), wp_get_original_image_path(), image_resize_dimensions(), wp_update_attachment_metadata().

Data stored

Name Kind Purpose
photopress_core_images option Settings: quality (integer), disabled_sizes (comma-separated size names).
photopress_images_assumed_quality option Quality assumed for images without _photopress_quality.
_photopress_quality post meta Quality the image's sizes were made at.
_photopress_sizes_signature post meta Written by 1.9.0. Not read in 2.0.0. Deleted when the image is regenerated.

REST routes

Both require manage_options (code).

Route Method Returns
/photopress/v1/image-sizes GET sizes (name, width, height, crop, core, enabled), images (count), outdated (count needing work), localFilesRemoved (WP Offload Media removes local files).
/photopress/v1/image-sizes/scope POST affected: images needing work with the settings given (quality, disabled_sizes).

The job is started with POST /photopress/v1/jobs and {"type":"images.regenerate","args":{}}. With "args":{"all":true} it remakes every size of every image, whatever its state. See Background Jobs.

Third-party integrations

WP Offload Media. PhotoPress reads its remove-local-file setting. When on, the tab shows a warning and hides Save and regenerate, and the job fails each image that needs work with "The original file is not on this server: Offload Media removed it." During regeneration PhotoPress returns true from as3cf_pre_update_attachment_metadata so the sizes are uploaded once, after they are all made. Without WP Offload Media, neither applies. See Offload Media and CDN.

Hooks PhotoPress provides

Hook Type Arguments When Code
photopress_imagick_limits filter array $limits (memory, map in bytes; thread in the job), bool $job Each time WordPress picks an image editor. A limit left out or not above 0 is left as ImageMagick has it. images.php#L613
photopress_image_sizes_regenerated action array $job When an images.regenerate job finishes (not when it is canceled). images.php#L675

Limits, quirks and known issues

  • Counting outdated images reads every image's metadata, 1,000 rows at a time. It runs when the tab loads and after each change on screen.
  • Images without _photopress_quality are assumed to have been made at the quality saved when PhotoPress first needed the value. Images made earlier at another quality are not flagged.
  • Switching a size off does not delete existing files. Nothing in PhotoPress removes them.
  • The job processes 5 images per batch, up to 10 seconds, rests between batches and waits while the server is busy. See Background Jobs.
  • A remake that dies (out of memory, timeout) leaves the image's stored file and metadata unchanged. Files it made under new names stay until the next attempt makes them again under the same names.
  • The ImageMagick limits are set with Imagick::setResourceLimit(), which applies to the whole PHP process.

Related

Clone this wiki locally