In this episode you'll understand ICC color profiles, embed and convert profiles with -profile, distinguish sRGB, AdobeRGB, and CMYK, and work with HDRI images and the EXR format.

In episode 10 you processed thousands of files with mogrify and scripts. But there's one problem that often appears in pipelines: an image that looks good on one computer changes color on another. A bright photo on your monitor turns dull, or a company logo looks greenish when printed. This problem rarely comes from the file — but from color management: how pixel numbers are translated into visible color.
This episode explains why colors can change, what an ICC profile is, how to embed and convert profiles with -profile, the difference between sRGB, AdobeRGB, and CMYK, and working with HDRI for wide dynamic range images.
Pixel values are just numbers — for example 255,0,0 for red. That number means nothing until we know the "language" it uses. An analogy is temperature: the number 25 is meaningless without a unit — 25 degrees Celsius and 25 degrees Fahrenheit are very different. Likewise, 255,0,0 in the sRGB color space is different from 255,0,0 in AdobeRGB.
A color space defines how numbers are mapped to visible color. If an image doesn't state its color space, every program will guess — and different guesses produce different appearances. This is the root of the color-changing problem across devices.
An ICC (International Color Consortium) profile is a file that describes the complete color space mapping of a device — like a passport stating "this image is written in the AdobeRGB language". Attaching a profile to an image is a way to embed the correct interpretation:
magick input.jpg -profile sRGB.icc output.jpg-profile sRGB.icc embeds the profile into the output file. The command magick input.jpg -profile sRGB.icc output.jpg is the most common way to use it. The processor that reads the image then knows exactly how to interpret its numbers, so the colors stay consistent across all profile-respecting applications.
Tip
On many Linux distributions, standard profiles are stored in /usr/share/color/icc/ or /usr/share/color/icc/colord/ — for example sRGB.icc and AdobeRGB1998.icc. Check with find /usr/share/color -name '*.icc' to see which profiles are available before converting.
Embedding a profile only marks the interpretation; converting changes the pixel numbers so they fit the destination color space. The command names both profiles at once — source then destination:
magick input-srgb.jpg \
-profile sRGB.icc -profile AdobeRGB1998.icc output-adobe.jpgThe pixel numbers are recomputed so the colors appear identical even when interpreted in AdobeRGB. Remember the order: the first profile is the file's original interpretation, the second is the destination interpretation. Converting then embedding are two different steps — you need both to truly move color spaces.
Three color spaces you'll encounter most often, each with its advantages and areas of use:
| Color Space | Color Gamut | When to Choose |
|---|---|---|
| sRGB | Smallest, web standard | All screen displays, photos for web and email |
| AdobeRGB | Wider than sRGB | Photos that will be printed, professional workflows |
| CMYK | Depends on the print profile | Documents to be offset-printed, commercial printing |
sRGB is the default language of screens and the internet — almost all browsers, operating systems, and phones assume images are sRGB. AdobeRGB reaches more saturated colors, but if the image is sent without a profile or displayed on an sRGB device, the colors look dull. CMYK is for print only: colors are computed from ink, not light, so its range differs and it must be converted with the appropriate print profile.
Important
Don't convert to CMYK without a clear print profile. The CMYK display on screen is always an approximation — every printing press has different ink characteristics. Converting to CMYK only makes sense if the goal is truly printing with the profile provided by the print shop.
-colorspace vs -profileBesides -profile, there's -colorspace, which also changes the color space. The difference is subtle but crucial:
magick input.jpg -colorspace sRGB output-1.jpg
magick input.jpg -set colorspace sRGB output-2.jpg-colorspace sRGB converts the pixel numbers from the active color space to sRGB — recomputing their values. Whereas -set colorspace sRGB only re-marks the interpretation without changing the numbers. Use -colorspace when the numbers must genuinely change; use -set when the file has no profile and you only need to tell it how to be read. A common mistake: using -set when you should use -colorspace, which results in double-shifted colors following the interpretation error.
Every color space has limits: values 0 to 1 on the normal scale. Ordinary images "clamped" to this range lose detail in very bright areas (highlights) and very dark areas (shadows). HDRI (High Dynamic Range) solves this by storing numbers beyond that range.
ImageMagick supports HDRI through the Q16-HDRI build, which works with floating point numbers in memory:
magick input.exr -define quantum:format=floating-point \
-resize 50% output.exr-define quantum:format=floating-point keeps the values in floating precision during processing, so highlights brighter than 1.0 aren't clipped. -depth sets the bit depth on output — for example -depth 16 for JPEG-2000 or 16-bit PNG.
Formats commonly carrying wide dynamic range are OpenEXR (.exr) and Radiance HDR (.hdr). Both are used in photography and visual effects because they store full exposure. When processing HDR inputs, watch out for two things:
magick foto.exr -auto-level foto-normal.jpg-auto-level stretches the histogram so an image with a very wide range still looks good after conversion to an ordinary format. Without the stretch, JPEG results from HDR files often look too dark or almost all white. The underlying concept: narrow output formats (JPEG, PNG) can't hold a wide range — you must decide which part to "sacrifice", and -auto-level helps make that decision automatically.
After embedding or converting profiles, don't just trust it — verify. magick identify -verbose shows all image metadata, including profiles:
magick identify -verbose output-adobe.jpg | grep -i 'icc'The icc: section of the output shows the name and size of the embedded profile — for example icc:profiles=icc/adobe-rgb. This check prevents a classic problem: an image that looks right on one machine actually carries an empty profile, so its colors go back to depending on other applications' guesses. Before sending assets out, get into the habit of checking that the color passport really traveled along.
The same habit applies to HDR files: after conversion, run magick identify -verbose output.exr and look at the Colorspace: and Depth: sections. The bit depth printed there tells you whether the floating point values were preserved or already dropped to integers — and that determines whether the next processor can use the remaining dynamic range.
In episode 11 you've understood why pixel numbers need interpretation, embedded profiles with -profile, converted between profiles with the source-then-destination order, distinguished sRGB, AdobeRGB, and CMYK along with their areas of use, correctly chosen -colorspace or -set, and worked with HDRI — -depth, -define quantum:format, and EXR and HDR inputs.
The takeaway: color is a language, and ICC profiles are its dictionary. A professional pipeline always ensures the profile is embedded, the destination color space is clear, and the bit depth is sufficient from the start — not fixing colors at the end.
In the next episode 12 we open up the world of modern formats and delegates: WebP, AVIF, JPEG XL, HEIC, SVG, and PDF along with their external library dependencies. See you then!