4

fellow programmers!

I'm trying to build a tool to replace an image within a .psd file. Atm I'm playing around with a PHP script that utilizes the imagick / ImageMagic extension.

I'd be extremely grateful if somebody would help me in how to accomplish this using imagick, or point me into an alternative direction.

The problem is that the image does not get replaced. I've tried using both setImage and addImage. If I export the file within the if statement, it shows the newly added image, however the changes are not reflected in the output.

This is the code I've tried.

        $src = Storage::path('file.psd');
        $psd = new Imagick($src);

        foreach ($psd as $index => $layer) {

            // Skip the first layer
            if (! $index) {
                continue;
            }

            $imageProperties = $layer->getImageProperties();
            $label = $imageProperties['label'] ?? '';

            if (str($label)->lower()->startsWith(['#'])) {
                $layer->removeImage();
                $layer->setImage(new Imagick(Storage::path('image.png')));

            }
        }


        $psd->mergeImageLayers(Imagick::LAYERMETHOD_MERGE);
        $psd->setImageFormat('png');
        $psd->writeImage(Storage::path('output.png'));
        $psd->clear();
        $psd->destroy();

Here's an example file that I've tried: https://mega.nz/file/H5FhQRRZ#Ta06TySXU5FIKAtx0DN87E3tjN2QSDoa3DAx0AQQbZ0

  • 2
    My initial response was going to be “PSD is not supported” but after a quick search I was proven wrong! Good to know! I’m seeing [people mention](https://legacy.imagemagick.org/discourse-server/viewtopic.php?t=32083) that the first (probably bottom-most) layer has to be a flattened layer, and possibly a background layer. Maybe try that? – Chris Haas Jan 21 '23 at 14:45
  • @ChrisHaas I tried that but couldn't get it to work, will try again this evening – platypusmaximus Jan 25 '23 at 11:18
  • https://github.com/hasokeric/php-psd Have you tried this tool? – alxndr_k Jan 25 '23 at 19:53
  • @alxndr_k it doesn't seem that there is any way to actually replace the data – platypusmaximus Jan 25 '23 at 21:27
  • Assuming you can get Photoshop and [extendedscript toolkit](https://community.adobe.com/t5/photoshop-ecosystem-discussions/how-to-download-extendscript-toolkit-for-2020/td-p/11114931), ([info](https://www.smashingmagazine.com/2013/07/introduction-to-photoshop-scripting/)), perhaps [this](https://stackoverflow.com/a/19384333/4935162) or [this](https://stackoverflow.com/a/67121633/4935162) scripts, in combination with [this](https://community.adobe.com/t5/photoshop-ecosystem-discussions/passing-arguments-to-the-jsx-file-from-command-line/td-p/1087954) cli method of running toolkit. – Yarin_007 Jan 26 '23 at 00:20
  • what do you mean `however the changes are not reflected in the output.`? – Yarin_007 Jan 26 '23 at 00:22
  • @Yarin_007 I think the photoshop extendedscript toolkit is probably the best way to do this, however afaik it'd be hard to set it up on ubuntu and have it work behind an API reliably. What I mean by changes are not reflected in the output - the output is written to png, however that png still has the old image on it. It's as if nothing was executed. – platypusmaximus Jan 26 '23 at 15:18

1 Answers1

0

Try with compositeImage() image

foreach ($psd as $index => $layer) {
    // Skip the first layer
    if (! $index) {
        continue;
    }

    $imageProperties = $layer->getImageProperties();
    $label = $imageProperties['label'] ?? '';

    if (str($label)->lower()->startsWith(['#'])) {
        $layer->compositeImage($newImage, Imagick::COMPOSITE_DEFAULT, 0, 0);
    }
}
Abdulla Nilam
  • 36,589
  • 17
  • 64
  • 85