I'm making a custom image style in Drupal 8.

It takes various parameters and passes the image to an external service for processing, and it now needs to read back the processed image from a file.

However, in applyEffect I'm expected to work with the Image $image object passed in.

The site is using the standard GD2 toolkit, which provides a load() method, but alas it's protected (presumably because the Image object that owns it would need updating).

Previously (porting this effect from D7) I was able to create a new Image object from the new image and replace the original object's resource and info properties, thus moving the altered image data into the image object. But this is no longer possible.

To summarise I want to:

public function applyEffect(ImageInterface $image) {
    $new_image_filename = call_some_external_process('/some/path');
    $image->load($new_image_filename); // ← this does not work :-)
    return TRUE;

1 Answer 1


Here's how I did it.

public function applyEffect(ImageInterface $image) {

    // Save the image and process it externally...
    $some_tempoaray_filename = '/tmp/foo';

    $toolkit = \Drupal::service('image.toolkit.manager')->getDefaultToolkit();
    // Re-call the existing Image object's constructor with the name of the
    // new file.
    $image->__construct($toolkit, $some_tempoaray_filename);
    // Next we have to make sure it loads the file into memory
    // because $image->save() requires it to be loaded, but this
    // happens outside of this function and we want to delete 
    // the $some_tempoaray_filename so as not to leave temp files.
    $toolkit->getResource(); // forces a load.
    // Now we can lose our temporary file.

    return TRUE;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.