Skip to content

[13.x] Fix incorrect image dimensions for HEIC - #61010

Merged
taylorotwell merged 2 commits into
laravel:13.xfrom
zachiler:fix/image-heic-dimensions
Aug 5, 2026
Merged

[13.x] Fix incorrect image dimensions for HEIC#61010
taylorotwell merged 2 commits into
laravel:13.xfrom
zachiler:fix/image-heic-dimensions

Conversation

@zachiler

@zachiler zachiler commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Image::dimensions(), width() and height() read the size with getimagesizefromstring(), which misreads HEIC — it either fails outright or reports the coded/padded frame size instead of the image's true display size:

HEIC getimagesize (current) actual display size
iPhone photo (large)* falsethrows 3024×4032
small single-tile 138×74 137×73

* Large HEICs are stored as a grid of smaller tiles; getimagesize can't resolve the assembled size and returns false (php-src #20863).

So on an ordinary iPhone upload ->width() throws today, and on smaller HEICs it silently returns the wrong number. (The conversion pipeline is fine — it goes through the driver, not getimagesize(); only the dimension inspectors are affected, which is what upload validation, aspect-ratio checks, and stored metadata rely on.)

Image::fromStorage('uploads/iphone-photo.heic')->width();
// before: ImageException "Unable to determine the dimensions of the image"
// after:  3024

$request->image('avatar')->cover(137, 73)->toHeic()->width();
// before: 138   after: 137

Fix

Follow-up to #60922, which added HEIC input/output support; dimensions() was left reading via getimagesizefromstring(). For HEIC/HEIF, dimensions are now read from the driver, which decodes the image and reports its true display size; every other format keeps its existing behaviour. HEIC requires the Imagick driver, so if the driver can't decode the image (e.g. GD) we fall back to the previous getimagesize() path — the default GD driver is unaffected.

Adds dimensions(string $contents): array to the Image\Driver contract and InterventionDriver, mirroring dominantColor() (#60932). Tests cover the driver routing, the GD fallback, and real-HEIC dimensions.

@zachiler
zachiler force-pushed the fix/image-heic-dimensions branch from 1b5ab5e to 08af07e Compare August 3, 2026 22:56
Image::dimensions(), width() and height() read the size with
getimagesizefromstring(), which misreads HEIC: it returns false for large
grid/tiled HEICs (so those methods throw) and reports the coded/padded frame
size for smaller ones. For HEIC/HEIF, dimensions are now read from the driver,
which decodes the image and reports its true display size, falling back to the
native reader when the driver can't decode the image (e.g. the GD driver).
Every other format is unchanged.

Adds dimensions() to the Image\Driver contract and InterventionDriver, mirroring
dominantColor(). Follow-up to laravel#60922.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@zachiler
zachiler force-pushed the fix/image-heic-dimensions branch from 08af07e to 8ae9200 Compare August 4, 2026 19:50
@taylorotwell
taylorotwell merged commit eade0a1 into laravel:13.x Aug 5, 2026
53 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants