Imagick - převod palety CMYK na RGB v PHP

Petr Wiedemann, 10. prosinec 2009

Imagick je rozšíření knihovny ImageMagick pro PHP. Podpora formátů závisí na konfiguraci knihovny ImageMagick. Například pro Gentoo mám v souboru package.use následující obsah.

media-gfx/imagemagick png jpeg jpeg2k tiff gs lcms

Pro změnu barevné palety obrázku nabízí Imagick metodu setImageColorspace. Pro její zjištění naopak metodu getImageColorspace.

Obě metody pracují s jednou z předdefinovaných konstant. Barevné paletě CMYK odpovídá konstanta Imagick::COLORSPACE_CMYK. Pouhé volání předchozích metod sice můžeme využít pro změnu palety, ovšem v některých případech může dojít k nepříjemné změně barev obrázků. Na následujících obrázcích je zdroj a výsledek pouhého volání metody setImageColorspace(Imagick::COLORSPACE_SRGB).

Zrojový CMYK obrázek Obrázek převedený do RGB

Problém je způsoben absencí ICC profilu ve zdrojovém obrázku. Abychom zachovali barvy při změně palety, musíme nahrát CMYK profil metodou profileImage.

Následující kousek skriptu změní barevnou paletu ze CMYK na SRGB a zmenší obrázek na maximální velikost strany 600 bodů.

<?php

  /**
   * Otevre obrazek, zmeni paletu na sRGB a prevede do JPEG.
   * 
   * @param string $src_file Zdrojovy obrazek.
   * @param string $dst_file Cilovy obrazek.
   */
  function ExportImage($src_file, $dst_file)
  {
    try
    {
      // Otevreni obrazku.
      $i = new Imagick($src_file);

      // Zjisteni palety.
      $cs = $i->getImageColorspace();

      // Zmena palety
      if ($cs == Imagick::COLORSPACE_CMYK)
      {
        // Nacteni profilu v obrazku.
        $profiles = $i->getImageProfiles('*', false);

        // Kontrola, jestli obrazek obsahuje icc profil.
        $has_icc_profile = (array_search('icc', $profiles) !== false);

        // Obrazek icc profil neobsahuje. Nacteni cmyk profilu ze souboru.
        if ($has_icc_profile === false)
        {
          $icc_cmyk = file_get_contents('USWebCoatedSWOP.icc');
          $i->profileImage('icc', $icc_cmyk);
        }

        // Zmena barevne palety, CMYK -> SRGB.
        $icc_rgb = file_get_contents('sRGB_v4_ICC_preference.icc');
        $i->profileImage('icc', $icc_rgb);
        $i->setImageColorspace(Imagick::COLORSPACE_SRGB);
      }

      // Zmena velikosti obrazku, pokud nektera
      // jeho strana presahuje 600 bodu.
      if ($i->getImageWidth() > 600 || $i->getImageHeight() > 600)
      {
        $i->resizeImage(600, 600, Imagick::FILTER_LANCZOS, true, true);
      }

      // Nastaveni formatu.
      $i->setImageCompression(Imagick::COMPRESSION_JPEG);
      $i->setImageCompressionQuality(95);
      $i->setImageFormat('jpeg');

      // Ulozeni obrazku.
      $i->writeImage($dst_file);

      $i->clear();
      $i->destroy();
      $i = null;
    }
    catch (ImagickException $e)
    {
      echo 'Chyba pri uprave obrazku: '.$e->getMessage();
    }
  }

?>

Zdroje, ze kterých jsem čerpal: