---
application: "Intervention Image"
version: "Version 4"
status: "stable"
---

# Upgrade Guide

## Upgrade from Intervention Image 3.x to 4.x

Learn how to migrate from Intervention Image version 3 to version 4. See what new features are available and what changes have been made in the update.


## New Features

### New Decoding Methods

The revised image decoding interface introduces a more transparent approach to
handling image sources, allowing image sources to be addressed directly instead
of relying on a single universal method. 

- `ImageManagerInterface::decode()`
- `ImageManagerInterface::decodePath()`
- `ImageManagerInterface::decodeBinary()`
- `ImageManagerInterface::decodeBase64()`
- `ImageManagerInterface::decodeDataUri()`
- `ImageManagerInterface::decodeSplFileInfo()`
- `ImageManagerInterface::decodeStream()`

[Read more about decoding methods](https://image.intervention.io/v4/basics/instantiation.md)

### Exceptions and more detailed Error Messages

At the same time, error and exception messages have been refined to provide
clear, immediate insight into what went wrong. These improvements include a
restructured exception system with a well-defined hierarchy that makes handling
exceptions easier.

[Read more about exceptions](https://image.intervention.io/v4/basics/error-handling.md)

### Enhancement of the Color System

- Functional [color format](https://image.intervention.io/v4/getting-started/formats#string-format.md) now supports syntax without comma
- New color generator object `Intervention\Image\Color` to [create and parse](https://image.intervention.io/v4/getting-started/formats#color-formats.md) more easily
- All colors now have full alpha channel support
- Support for OkLab and Oklch color space
- New enum `NamedColor::class` for css color names.
- New [Color modifier methods](https://image.intervention.io/v4/basics/colors#transforming-colors.md) `ColorInterface::withTransparency()`, `ColorInterface::withBrightness()`, `ColorInterface::withSaturation` and `ColorInterface::withInversion()`

### More New Features

- DataUri::class
- Alignment::class
- New method `DriverInterface::version()` to check internal version of driver
- Origin::format()
- Support for encoding ICO-Format

## API Changes

### High Impact Changes

It is very likely that you will need to make these adjustments when you update to version 4.

- Intervention Image 4 now requires PHP 8.3.0 or greater.
- `ImageManagerInterface::read()` is now handled by `ImageManagerInterface::decode()` or the [other decode methods](https://image.intervention.io/v4/basics/instantiation.md)
- `ImageManagerInterface::withDriver()` is now handled by [Image::usingDriver()](https://image.intervention.io/v4/basics/configuration-drivers#create-a-new-image-manager-instance-with-static-helper-methods.md)
- `ImageManagerInterface::animate()` is replaced by universal [ImageManagerInterface::createImage()](https://image.intervention.io/v4/basics/instantiation#create-images.md)
- `ImageInterface::toJpeg()` and `ImageInterface::toJpg()` are now handled by [ImageInterface::encodeUsingFormat()](https://image.intervention.io/v4/basics/image-output#encode-images-using-format.md)
- `ImageInterface::toPng()` is now handled by [ImageInterface::encodeUsingFormat()](https://image.intervention.io/v4/basics/image-output#encode-images-using-format.md)
- `ImageInterface::toGif()` is now handled by [ImageInterface::encodeUsingFormat()](https://image.intervention.io/v4/basics/image-output#encode-images-using-format.md)
- `ImageInterface::toJp2()` and `ImageInterface::toJpeg2000()` are replaced by [ImageInterface::encodeUsingFormat()](https://image.intervention.io/v4/basics/image-output#encode-images-using-format.md)
- `ImageInterface::toWebp()` is replaced by [ImageInterface::encodeUsingFormat()](https://image.intervention.io/v4/basics/image-output#encode-images-using-format.md)
- `ImageInterface::toBitmap()` and `ImageInterface::toBmp()` are replaced by [ImageInterface::encodeUsingFormat()](https://image.intervention.io/v4/basics/image-output#encode-images-using-format.md)
- `ImageInterface::toAvif()` is replaced by [ImageInterface::encodeUsingFormat()](https://image.intervention.io/v4/basics/image-output#encode-images-using-format.md)
- `ImageInterface::toHeic()` is replaced by [ImageInterface::encodeUsingFormat()](https://image.intervention.io/v4/basics/image-output#encode-images-using-format.md)
- `ImageInterface::toTiff()` and `ImageInterface::toTif()` are replaced by [ImageInterface::encodeUsingFormat()](https://image.intervention.io/v4/basics/image-output#encode-images-using-format.md)
- `ImageInterface::encodeByMediaType()` is replaced by [ImageInterface::encodeUsingMediaType()](https://image.intervention.io/v4/basics/image-output.md)
- `ImageInterface::encodeByPath()` is replaced by [ImageInterface::encodeUsingPath()](https://image.intervention.io/v4/basics/image-output.md)
- `ImageInterface::encodeByExtension()` is replaced by [ImageInterface::encodeUsingFileExtension()](https://image.intervention.io/v4/basics/image-output.md)
- `ImageInterface::encodeByExtension()` is replaced by [ImageInterface::encodeUsingFileExtension()](https://image.intervention.io/v4/basics/image-output.md)
- `ImageInterface::pickColor()` was renamed to [ImageInterface::colorAt()](https://image.intervention.io/v4/basics/colors#read-color-of-a-pixel.md) and signature has changed, argument `$frame_key` is now `$frame`
- `ImageInterface::pickColors()` was renamed to [ImageInterface::colorsAt()](https://image.intervention.io/v4/basics/colors#read-all-colors-of-certain-pixels-in-animated-images.md)
- `ImageInterface::pad()` was renamed to [ImageInterface::containDown()](https://image.intervention.io/v4/modifying-images/resizing#contain-resizing-without-upscaling.md) with different signature
- [ImageInterface::flip()](https://image.intervention.io/v4/modifying-images/effects#mirror-images.md) now handles both vertical and horizontal mirroring with new `direction` parameter
- `ImageInterface::flop()` was removed. Use [ImageInterface::flip()](https://image.intervention.io/v4/modifying-images/effects#mirror-images.md) with direction parameter `Direction::HORIZONTAL`
- `ImageInterface::place()` was renamed to [ImageInterface::insert()](https://image.intervention.io/v4/modifying-images/inserting.md) with a different signature. `offset_x` was renamed to `x` and `offset_y` was renamed to `y`, `opacity` was renamed to `transparency` with `float` instead of `int` and updated argument order
- Signatures of [ImageInterface::drawRectangle()](https://image.intervention.io/v4/modifying-images/drawing.md), [ImageInterface::drawLine()](https://image.intervention.io/v4/modifying-images/drawing.md), [ImageInterface::drawEllipse()](https://image.intervention.io/v4/modifying-images/drawing.md), [ImageInterface::drawCircle()](https://image.intervention.io/v4/modifying-images/drawing.md), [ImageInterface::drawPolygon()](https://image.intervention.io/v4/modifying-images/drawing.md) and [ImageInterface::drawBezier()](https://image.intervention.io/v4/modifying-images/drawing.md) have changed
- Method `ImageInterface::save()` only processes known image file extensions. Use `EncodedImageInterface::save()` if you want to save with unknown file extensions.
- `EncodedImageInterface::toDataUri()` now returns `DataUriInterface::class` instead of `string`
- Method `FontInterface::filename()` is replaced by [FontInterface::filepath()](https://image.intervention.io/v4/modifying-images/text-fonts#font-file.md)
- Method `FontInterface::hasFilename()` is replaced by `FontInterface::hasFile()`
- Method `FontInterface::setFilename()` is replaced by `FontInterface::setFilepath()`
- Method `ColorInterface::convertTo()` was renamed to [ColorInterface::toColorspace()](https://image.intervention.io/v4/basics/colors#transform-colors-between-colorspaces.md)
- [Config::class](https://image.intervention.io/v4/basics/configuration-drivers#configuration-options.md) option `blendingColor` was renamed to `backgroundColor`
- Method `ImageInterface::rotate()` rotates clockwise by default.
- `ImageInterface::blendTransparency()` was renamed to [ImageInterface::fillTransparentAreas()](https://image.intervention.io/v4/basics/colors#merge-transparent-areas-with-color.md) with a different signature allowing (semi) transparent colors
- `ImageInterface::setBlendingColor()` was renamed to [ImageInterface::setBackgroundColor()](https://image.intervention.io/v4/basics/colors#set-the-background-color.md)
- `ImageInterface::blendingColor()` was renamed to [ImageInterface::backgroundColor()](https://image.intervention.io/v4/basics/colors#read-the-background-color.md)
- Color value string `transparent` is no longer supported. Use [Intervention\Image\Color::transparent()](https://image.intervention.io/v4/basics/colors#transparency.md) instead
- Parameter `$prefix` of [ColorInterface::toHex()](https://image.intervention.io/v4/basics/colors#transform-colors-to-hexadecimal-notation.md) has now a `boolean` type
- Method `ImageInterface::reduceColors()` has a different type and default value of the argument `$background`. Background defaults now to the configured background color instead of `transparent`.

### Medium Impact Changes

It is possible that you will need to make these adjustments when updating if you have used these parts of the API.

- Removed `ColorInterface::toArray()` use `ColorInterface::channels()` and map to desired format
- Removed `ColorInterface::normalize()` use `ColorInterface::channels()` and map to desired format
- Changed default value for `background` to `null` in [ImageInterface::rotate()](https://image.intervention.io/v4/modifying-images/resizing#resize-image-canvas.md)
- Changed default value for `background` to `null` in [ImageInterface::resizeCanvas()](https://image.intervention.io/v4/modifying-images/resizing#resize-image-canvas.md)
- Changed default value for `background` to `null` in [ImageInterface::resizeCanvasRelative()](https://image.intervention.io/v4/modifying-images/resizing#resize-image-canvas.md)
- Changed default value for `background` to `null` in [ImageInterface::contain()](https://image.intervention.io/v4/modifying-images/resizing#contain-resizing-1.md)
- Changed default value for `background` to `null` in [ImageInterface::containDown()](https://image.intervention.io/v4/modifying-images/resizing#contain-resizing-without-upscaling.md) former `ImageInterface::pad()`
- Changed default value for `background` to `null` in [ImageInterface::crop()](https://image.intervention.io/v4/modifying-images/resizing#crop-image.md)
- Signature of [ImageInterface::crop()](https://image.intervention.io/v4/modifying-images/resizing#crop-image.md) changed from `offset_x` to `x` and `offset_y` to `y`
- Attribute `$per_unit` has changed to `$unit` with different signature in `Resolution::class`
- Method `DrawableFactoryInterface::init()` is replaced by `DrawableFactoryInterface::create()`
- Method `DrawableFactoryInterface::create()` is replaced by `DrawableFactoryInterface::drawable()`
- `DriverInterface::handleInput()` is replaced by `DriverInterface::handleImageInput()`, `DriverInterface::handleColorInput()`
- `CollectionInterface::empty()` was renamed to `CollectionInterface::clear()`
- `FontFactory::valign()` was replaced with [FontInterface::align()](https://image.intervention.io/v4/modifying-images/text-fonts.md)
- `FontInterface::valignment()` was renamed to [FontInterface::verticalAlignment()](https://image.intervention.io/v4/modifying-images/text-fonts.md)
- `FontInterface::setValignment()` was renamed to [FontInterface::setVerticalAlignment()](https://image.intervention.io/v4/modifying-images/text-fonts.md)
- `FontInterface::alignment()` was renamed to [FontInterface::horizontalAlignment()](https://image.intervention.io/v4/modifying-images/text-fonts.md)
- `FontInterface::setAlignment()` was renamed to [FontInterface::setHorizontalAlignment()](https://image.intervention.io/v4/modifying-images/text-fonts.md)
- `ImageInterface::greyscale()` was renamed to [ImageInterface::grayscale()](https://image.intervention.io/v4/modifying-images/effects#convert-image-to-a-grayscale-version.md)
- `ColorInterface::isGreyscale()` was renamed to `ColorInterface::isGrayscale()`
- Alpha channel values in `__construct()` or `create()` methods of colors are now defined as float values between `0` and `1`
- `FrameInterface::dispose()` was renamed to `FrameInterface::disposalMethod()`
- `FrameInterface::setDispose()` was renamed to `FrameInterface::setDisposalMethod()`
- `ImageManagerInterface::driver()` was removed but you can use the public `$driver` property.
- `FileInterface::toFilePointer()` was renamed to `FileInterface::toStream()`
- Color format string `transparent` is no longer supported. Use [Intervention\Image\Color::transparent()](https://image.intervention.io/v4/basics/colors#transparency.md) instead

### Low Impact Changes

You will probably only need to make these adjustments when updating if you use
the API extensively and have written your own drivers or modifiers.

- `BlendTransparencyModifer::class` was renamed to `FillTransparentAreasModifier::class`
- `ProfileInterface::class` requires implementation of `::fromPath()`
- `DriverInterface::class` requires implementation of `__construct()`
- `DriverInterface::class` requires implementation of `createCore()`
- Replace `DriverInterface::specialize()` with `DriverInterface::specializeModifier()`, `DriverInterface::specializeAnalyzer()`, `DriverInterface::specializeDecoder()` and `DriverInterface::specializeEncoder()`
- `DriverInterface::handleColorInput()` has null as default
- Signature of `FrameInterface::__construct()` has changed, argument `$offset_left` is now `$offsetLeft` and `$offset_top` is now `$offsetTop`
- Signature of `PixelColorAnalyzer::__construct()` has changed, argument `$frame_key` is now `$frame`
- `ColorChannelInterface::max()` and `ColorChannelInterface::min()` are now static
- Method `ColorChannelInterface::toInt()` was removed use `ColorChannelInterface::value()` instead
- Method `ColorChannelInterface::colorFromNormalized()` requires now a static implementation
- Method `ColorChannelInterface::normalize()` was renamed to `ColorChannelInterface::normalizedValue()`
- `CoreInterface::class` now requires implementation of `CoreInterface::meta()`
- `RectangleResizer::class` was renamed to `Resizer::class`
- `GreyscaleModifier::class` was renamed to `GrayscaleModifier::class`
- `DrawableFactoryInterface::__invoke()` was removed, use `DrawableFactoryInterface::build()` or `DrawableFactoryInterface::drawable()`
- `FontFactory::__invoke()` was removed, use `FontFactory::build()` or `FontFactory::font()`
- `AnimationFactory::__invoke()` was removed, use `AnimationFactory::build()` or `AnimationFactory::animation()`
- `InputHandler::withDecoders()` was renamed to `InputHandler::usingDecoders()`
- Interface `ColorInterface::class` now requires to implement `ColorInterface::withTransparency()`
- Interface `ColorInterface::class` now requires to implement `ColorInterface::alpha()`
- Removed `topLeftPoint()` and `bottomRightPoint()` from `Rectangle::class`
- Removed `ColorChannelInterface::__construct()` from interface
- Removed `DriverInterface::createAnimation()`
- `SizeInterface::relativePositionTo()` was renamed to `SizeInterface::offsetTo()`
- `DrawableInterface` requires the implementation of `factory()` and `adjust()`.
- `ColorProcessorInterface::colorToNative()` was renamed to `ColorProcessorInterface::export()`
- `ColorProcessorInterface::nativeToColor()` was renamed to `ColorProcessorInterface::import()`

---

## Become a Sponsor

### Intervention Image needs your help to keep the project going

Intervention Image is non-commercial, open source licensed and completely free to use. The considerable
effort required to maintain and develop the software is only possible with the financial support
of sponsors. There are two ways in which you can support this project.

- Support via [GitHub Sponsors](https://github.com/sponsors/Intervention)
- Support via [Ko-Fi](https://ko-fi.com/interventionphp)