1

I've created a method called convertImage() that uses Imagick to convert any file into a jpeg file.

I've added ICC profiles to deal with CMYK to RGB conversions.

This is working well for thousands of files except for a few PSD files.

public static function convertImage($localPath, $destination, $max_width, $max_height)
{
    $image = new Imagick();
    $image->readImage($localPath);

    if(pathinfo($localPath, PATHINFO_EXTENSION) === "psd"){
        $image->setIteratorIndex(0);
    }

    if ($image->getImageColorspace() == Imagick::COLORSPACE_CMYK) {
        $profiles = $image->getImageProfiles('*', false);
        // we're only interested if ICC profile(s) exist
        $has_icc_profile = (array_search('icc', $profiles) !== false);
        // if it doesnt have a CMYK ICC profile, we add one
        if ($has_icc_profile === false) {
            $icc_cmyk = file_get_contents(__DIR__ . '/../icc/USWebUncoated.icc');
            $image->profileImage('icc', $icc_cmyk);
            unset($icc_cmyk);
        }
        // then we add an RGB profile
        $icc_rgb = file_get_contents(__DIR__ . '/../icc/sRGB_v4_ICC_preference.icc');
        $image->profileImage('icc', $icc_rgb);
        unset($icc_rgb);
    }
    $image->stripImage();
    $image->setImageFormat('jpg');
    $image->setImageCompressionQuality(85);
    $image->writeImage($destination);
    $image->clear();
    $image->destroy();

    // we resize files in a second time because of a imagick bug (pictures become black)
    $image = new Imagick();
    $image->readImage($destination);
    $image->scaleImage($max_width, $max_height, true);
    $image->writeImage($destination);
    $image->clear();
    $image->destroy();
}

For some PSD files I got this Exception:

maximum channels exceeded `ART00060111_B.psd' @ error/psd.c/ReadPSDImage/1085

And for others:

Unable to read the file: ART00060111_A.psd

You can find the files here: [ART00060111_A.psd, ART00060111_B.psd, USWebUncoated.icc, sRGB_v4_ICC_preference.icc]

Here is my phpinfo() concerning Imagick:

phpinfo (Imagick section)

Florian Lemaitre
  • 5,905
  • 2
  • 21
  • 44
  • Please let me know if you need any additional informations – Florian Lemaitre Jul 20 '17 at 08:58
  • which imagick version? – NID Jul 20 '17 at 09:23
  • The maximum number of channels **ImageMagick** can read from a PSD is 56, but your image does not have that many channels. I can only guess that there is some incompatibility between your version of Photoshop and the one that the **ImageMagick** developers can read. The PSD format is notoriously poorly documented https://stackoverflow.com/a/5355949/2836621 I note that the failing image has *"Layer Effects"* on it - do images that work have these effects or could it be these that are causing the issue? – Mark Setchell Jul 20 '17 at 09:23
  • ImageMagick cannot handle Layer Effects or Group Layers or the like. It can only handle simple plain layers with no layer effects. The best thing when processing PSD files is to extract the first layer, which should be the flattened layer. So do something like convert image.psd[0] ... result.jpg – fmw42 Jul 20 '17 at 16:28
  • btw if you want just the first page, you can open the image with the filename `$localPath . "[0]"` – Danack Jul 20 '17 at 22:50
  • I've added my phpinfo on production server. We can see that ImageMagick is up to date but Imagick seems to be out of date and not stable. https://pecl.php.net/package/imagick – Florian Lemaitre Jul 21 '17 at 09:35

2 Answers2

0

May be this will help you:

Imagick::autoLevelImage

This Adjusts the levels of a particular image channel by scaling the minimum and maximum values to the full quantum range.

Example #1 Imagick::autoLevelImage()

<?php
function autoLevelImage($imagePath) {
    $imagick = new \Imagick(realpath($imagePath));
    $imagick->autoLevelImage();
    header("Content-Type: image/jpg");
    echo $imagick->getImageBlob();
}

?>
NID
  • 3,238
  • 1
  • 17
  • 28
0

The following commands work fine for me on ImageMagick 6.9.9.0 Q16 Mac OSX. As I mentioned in my comment earlier, just convert the first layer of the PSD file. Sorry, I do not know Imagick well. So here is the equivalent ImageMagick command.

convert ART00060111_A.psd[0] -profile USWebUncoated.icc -profile sRGB_v4_ICC_preference.icc ART00060111_A.jpg

enter image description here

convert ART00060111_B.psd[0] -profile USWebUncoated.icc -profile sRGB_v4_ICC_preference.icc ART00060111_B.jpg

enter image description here

P.S. It looks like you are trying to access the first layer via $image->setIteratorIndex(0);. So I am not sure why you are getting such messages. Can you try my commands in a terminal window? Do they work there? If not, then perhaps there is a bug in your version of ImageMagick.

Also why do you strip the jpg of the profiles via $image->stripImage();. For best cross-platform and various browser viewing, you get a more consistent looking result if you leave the sRGB profile.

What bug are you mentioning that causes you to have to start Imagick over to do the resize?

fmw42
  • 46,825
  • 10
  • 62
  • 80