Get ICC profile image using PHP or Imagick

I have been struggling with this problem all day and am surprised that I cannot find any documentation!

I upload images to the site and would like to get the name of each ICC image profile and use it in the image description. So far, standard PHP does not produce any results. I checked the images using Photoshop, Bridge, and Exiftool, and each of them defined an embedded profile.

<?php $info = exif_read_data($image); echo 'ICC Profile: '.$info['ICC_Profile'].'<br>'; echo 'ICC Profile: '.$info['CurrentICCProfile'].'<br>'; echo 'ICC Profile: '.$info['ColorSpace'].'<br>'; ?> 

Imagick gave the best results:

 $imagick = new Imagick(); $imagick->readImage($image); print_r ($imagick->getImageProfiles("icc",true)); 

Create an array that actually mentions the profile but the usable string. Any help was appreciated.

I use the following versions:

PHP version 5.2.17 - imagick module version 3.0.1 - ImageMagick version 6.7.6-8

And print_r returns (for ICC ProPhoto RGB profile):

Array ([icc] => KCMSmntrRGB XYZ: acspMSFTKODAROMM + KODAcprtHdesc \ wtpt rTRC gTRC bTRC rXYZgXYZbXYZ, dmnd @ndmdd mmod (textCopyright (c) Eastman Kodak Company, 1999, all rights reservedPhotoXPY RGBPhotoPz RGBPZDZ RGBPdesc RGBPdesc curds XYZ "> XYZ -descKODAK KODAKKODAKdesc'Reference Output average metric (ROMM) (Average output medium Metric (ROMM)" Reference average metric (ROMM) mmod;)

in full (from Exiftool):

 Profile CMM Type : KCMS Profile Version : 2.1.0 Profile Class : Display Device Profile Color Space Data : RGB Profile Connection Space : XYZ Profile Date Time : 1998:12:01 18:58:21 Profile File Signature : acsp Primary Platform : Microsoft Corporation CMM Flags : Not Embedded, Independent Device Manufacturer : KODA Device Model : ROMM Device Attributes : Reflective, Glossy, Positive, Color Rendering Intent : Perceptual Connection Space Illuminant : 0.9642 1 0.82487 Profile Creator : KODA Profile ID : 0 Profile Copyright : Copyright (c) Eastman Kodak Company, 1999, all rights reserved. Profile Description : ProPhoto RGB Media White Point : 0.9642 1 0.82489 Red Tone Reproduction Curve : (Binary data 14 bytes, use -b option to extract) Green Tone Reproduction Curve : (Binary data 14 bytes, use -b option to extract) Blue Tone Reproduction Curve : (Binary data 14 bytes, use -b option to extract) Red Matrix Column : 0.79767 0.28804 0 Green Matrix Column : 0.13519 0.71188 0 Blue Matrix Column : 0.03134 9e-005 0.82491 Device Mfg Desc : KODAK Device Model Desc : Reference Output Medium Metric(ROMM) Make And Model : (Binary data 40 bytes, use -b option to extract) 
+7
source share
1 answer

I am not sure if this applies to all images. At least the images that I have have this information in their β€œProperties”. Thus, in order to get the name for the printed profile, it should work as follows:

 $imagick = new imagick('/some/filename'); $profile = $imagick->getImageProperties('icc:model', true); /** * If the property 'icc:model' is set $profile now should be: * array( 'icc:model' => 'ICC model name') */ 

If you want to see all the properties that are set for an image, you can examine the image manually using identify -verbose /some/filename . There you need to look for "Properties:", the name of the ICC should be indicated there.

The above method is to get the ICC profile name. If you really need the ICC name from the icc profile, you can take a look at the ICC profile specification

In short:

  • The first 128 bytes is the header. This is followed by a tag table, where the first 4 bytes represent the size of the table.
  • Each tag consists of 4 byte triplets. The first 4 bytes is the name of the tag. The next four bytes are the data offset in the icc file. The next four bytes determine the size of the tag data.

We are interested in the tag "desc" (see page 63 in the specification).

  • The description itself starts again with "desc", then four bytes are reserved. The next four bytes determine the size of the ICC profile name.

In code, it works as follows:

 $image = new imagick('/path/to/img'); try { $existingICC = $image->getImageProfile('icc'); } catch (ImagickException $e) { // Handle it $existingICC = null; } if($existingICC) { // Search the start of the description tag in the tag table.: // We are not looking in the 128 bytes for the header + 4 bytes for the size of the table $descTagPos = stripos( $existingICC, 'desc', 131 ); if( $descTagPos === false) { // There is no description, handle it. } else { // This is the description Tag ( 'desc'|offset|size each with a size of 4 bytes $descTag = substr( $existingICC, $descTagPos, 12 ); // Get the offset out of the description tag, unpack it from binary to hex and then from hex to decimal $descTagOffset = substr ( $descTag, 4, 4 ); $descTagOffset = unpack( 'H*', $descTagOffset ); $descTagOffset = hexdec( $descTagOffset[1] ); // Same for the description size $descTagSize = substr ( $existingICC, $descTagPos + 8, 4 ); $descTagSize = unpack('H*', $descTagSize); $descTagSize = hexdec( $descTagSize[1] ); // Here finally is the descripton $iccDesc = substr( $existingICC, $descTagOffset, $descTagSize ); // See page 63 in the standard, here we extract the size of the ICC profile name string $iccNameSize = substr( $iccDesc, 8, 4 ); $iccNameSize = unpack( 'H*', $iccNameSize); $iccNameSize = hexdec( $iccNameSize[1]); // Finally got the name. $iccName = substr( $iccDesc, 12, $iccNameSize ); echo "ICC name: $iccName\n"; } } 
+5
source

All Articles