php-imagine / Imagine

PHP Object Oriented image manipulation library
https://imagine.readthedocs.io
Other
4.42k stars 529 forks source link

Is there an inverse to getGdResource() #837

Open jcogs-design opened 2 years ago

jcogs-design commented 2 years ago

Issue description

The getGdResource() method extracts the GDResource component from a GD type Image object.

However there does not appear to be any clean way to generate or update the Image object from a GDResource type entity.

This is unfortunate.

If (for example) if you need to apply a process to an image for which no Image methods exist (e.g. apply an arbitrary laplacian type filter) then the only option (in GD universe) is to export the image resource, apply the process using GD primitives and then ... you are stuck. The Imagine read() method apparently only reads GD resources from disk, so it would appear to proceed with processing you need to write the partially processed image to disk and read it back again (or if that doesn't work, write out partially processed image in an image file format and create a new Image instance by reading that back again).

A better solution would be for there to be a way to simply load a GD resource back into the Image object. ...

What version of Imagine are you using?

1.3.2

What's the PHP version you are using?

8.0.25

What's the imaging library you are using [gd/imagick/gmagick/any]?

GD2

What's the imaging library configuration

GD Version: "2.3.3" FreeType Support: true FreeType Linkage: "with freetype" GIF Read Support: true GIF Create Support: true JPEG Support: true PNG Support: true WBMP Support: true XPM Support: true XBM Support: true WebP Support: true BMP Support: true TGA Read Support: true JIS-mapped Japanese Font Support: false

Minimal PHP code to reproduce the error:


$imagine_object = new Imagine\Gd\Imagine(); // Creates new Imagine GD object
$image_object = $imagine_object->load($image); // Creates a new Image GD object
$gd_resource = $image_object->getGdResource();
... do stuff ...
$modified_image_object = $imagine_object->read($gd_resource); // Fails... :(
ausi commented 2 years ago

Why not use the ClassFactory as outlined in https://github.com/php-imagine/Imagine/issues/834#issuecomment-1312522223 ?

jcogs-design commented 2 years ago

Because (as described) that solution appears to require writing the work-in-progress image to disk... which is what I am trying to avoid... or am I misunderstanding your suggestion?

ausi commented 2 years ago

How about this?

$imagine_object = new Imagine\Gd\Imagine(); // Creates new Imagine GD object
$image_object = $imagine_object->load($image); // Creates a new Image GD object
$gd_resource = $image_object->getGdResource();
... do stuff ...
$modified_image_object = (new Imagine\Factory\ClassFactory())->createImage(
    Imagine\Factory\ClassFactoryInterface::HANDLE_GD, 
    $gd_resource, 
    new Imagine\Image\Palette\RGB(), 
    new Imagine\Image\Metadata\MetadataBag(),
);
jcogs-design commented 2 years ago

How about this?

Perfect - thanks!

jcogs-design commented 2 years ago

Is there a simple / reliable way to determine which Image library an Imagine object is using? Have a custom filter that has different implementations for GD vs the other libraries - unclear what the best / most efficient method of routing image object to correct filter variant might be. Am using get_class() on the image object and searching for Image library in string returned currently, but this seems a bit clunky.

ausi commented 2 years ago
if ($image instanceof \Imagine\Gd\Image) {
    //...
} elseif ($image instanceof \Imagine\Imagick\Image) {
    //...
} elseif ($image instanceof \Imagine\Gmagick\Image) {
    //...
}
jcogs-design commented 2 years ago

Thanks - much neater