ImageMagick Colour Management

Hi, I am starting to use ImageMagick for the first time and need a little help, particularly with colour management. Being on Mint 20.3, ImageMagick version is 6.something

The command I am working on is resize. I currently have this:
convert -quiet /directory/‘Image Name.tif’ -filter Sinc -resize ‘1600’ -quality ‘95’ /directory/NewName.jpg

I had to use -quiet, for if I didn’t I would get this message:
“convert-im6.q16: Unknown field with tag 36867 (0x9003) encountered. `TIFFReadDirectory’ @ warning/tiff.c/TIFFWarnings/949.”

No idea what that means. Anyway, the image I’m working on has been first exported as 16 bit tif out of darktable with linear rec 2020 colour space. However, when I run identify -verbose it tells me the colorspace is sRGB which is wrong (can confirm by opening the same tiff in Krita. So I guess Krita recognises the profile but ImageMagick doesn’t).

So how do I get ImageMagick to recognise (assign) the current profile? (I want the downsizing to take place in linear space)
Then how do I convert the profile to sRGB once complete? And will this embed that profile in the jpg output?

Also, a question on the -intent command. Will that be useful to determine what happens to OOG colour when converting the profile, or is it what gets embedded in the jpg output?

My guess is the command will look something like:
convert -quiet /directory/‘Image Name.tif’ -set profile /directory/name.icc -filter Sinc -resize ‘1600’ -profile /directory/sRGB.icc -intent ‘Perceptual’ -quality ‘95’ /directory/NewName.jpg

But i haven’t run it, for even if it works I might not be able to confirm the colour management worked as intended, so I seek guidance here. Many thanks!

Depending on your needs, this can be ignored - LibTIFF (that IM is using for parsing the metadata) is unfortunately not aware of the redundancy between Exif standard tags (located in the Exif IFD) and TIFF/EP standard tags (located in the root IFD), and so complains when it sees a TIFF/EP tag as it only assumes the Exif location. If you need the DateTimeOriginal value (and possibly others) in your final jpg, you’ll have to copy later from the raw/tif using e.g. exiftool or exiv2.

1 Like

I think what you’re looking for is

convert input.tif -set colorspace RGB <insert other operations here> -profile sRGB.icc -depth 8 output.jpg

The sRGB reported by identify is misleading, it just means it assumes non-linear input data… If you do identify -verbose, you’ll see it actually finds the embedded ICC profile.

I wouldn’t use -set colorspace RGB.

@Soupy: first, try the following command:

identify -verbose yourfile.tiff

Near the bottom of the text output, look for something like this:

  Profiles:
    Profile-icc: 476 bytes
  Properties:
    comment:
    date:create: 2020-01-17T02:31:02+00:00
    date:modify: 2020-01-17T03:33:42+00:00
    date:timestamp: 2022-07-21T13:53:11+00:00
    exif:ExposureTime: 0.001562
    exif:FNumber: 8.000000
    exif:FocalLength: 105.000000
    exif:ISOSpeedRatings: 200
    icc:copyright: auto-generated by dcraw
    icc:description: XYZ

The first two lines tell us the file has an embedded profile. “icc:description” tells us the colorspace, in this case XYZ. For you it would say “REC2020” or similar.

When an image file has an embedded profile, you can convert to a new profile with “-profile NewName.icc”. This will change pixel values and embed the new profile.

convert yourfile.tiff -profile newname.icc out.tiff

Provide the full path to the ICC file if it isn’t in your current directory. IM comes with sRGB.icc. You can also use any of Elle’s profiles at elles_icc_profiles/profiles at master · ellelstone/elles_icc_profiles · GitHub

If, for some reason, there is no embedded profile, then you need to assign one. “-profile” will also do that. A second “-profile” will convert to a new profile.

EDIT:

(I want the downsizing to take place in linear space)

Convert to linear REC2020, then do the resizing, then convert to whatever profile you want. For example, assuming a profile is already embedded:

convert yourfile.tiff -profile Rec2020-elle-V2-g10.icc -filter Sinc -resize 1600 -profile sRGB-elle-V2-srgbtrc.icc quality 95 out.jpg

Incidentally, IM v7 has been out for a few years now. I suggest you upgrade.

1 Like

Actually, you don’t need/want the first “-profile Rec2020-elle-V2-g10.icc” if the linear Rec2020 profile is already embedded in the TIFF from dt export, otherwise this will lead to an unnecessary conversion (which is close to, but not really identity due to integer round trip operations).

1 Like

Agreed.

Thanks! I was looking at colorspace as opposed to icc description. The embedded profile is indeed there.

I did download and run the appimage but when I type commands using magick instead of convert it says “Command ‘magick’ not found”

Sorry, I know nothing about appimages.

As @kmilos says, if the embedded ICC colour profile is already in the space you want (linear REC2020) then you don’t need -profile Rec2020-elle-V2-g10.icc to convert it to that space, and you can just do:

convert yourfile.tiff -filter Sinc -resize 1600 -profile sRGB-elle-V2-srgbtrc.icc quality 95 out.jpg

… or use any sRGB ICC profile you want.

1 Like

Got it, thanks.
If I was to put this command in a shell script, would it be possible to have
-resize (=image width - x)
where x was a defined value?
In other words, can it perform math?

You don’t have to , it’s just a warning.

There can be quite a difference in how certain things are handled in the 6.x versions. So knowing this MIGHT come on handy.

V7 has been out ror years… Just saying.

Not really . Not in imagemagick speak anyway :). The image is rgb, sRGB , lab, cmyk , etc… which profile is used , is completely separate from this in imagemagick.

Imagemagick itself also does very little with this profile image. If you say ‘red’ it doesn’t use the profile , it jus tuaed rgb 255,0,0 for example .
It can convert from and to different profiles .

So , if you read a tif, scale and save to jpg… there is a good chance it just copies over the profile , not caring what it means . This should be easy to test if you view the output file .

The -profile switch converts to another profile , OR assigns if no profile is there yet . This always itches with me, cause how do you know for sure there is a profile and its picked up or not :wink:.

The +profile switch can remove a profile .

So if i want to be sure, i always use +profile to clear all profiles , then use -profile to assign a profile , then set intent and black point compensation if wanted , then use another -profile to convert to a profile , then save .

magick inputfile.tif +profile "*" -profile linear_rec2020.icc -intent relative -black-point-compensation -profile srgb.icc outputfile.jpg . Just to give an example.

If you are sure there is a profile in the image (use identify -verbose to search for it ) you could drop the first +profile and -profile. But if you know the profile of an image , you might as well do what i did .

If you need icc files to assign and convert to, you can ‘convert’ an image file to a .icc file to extract the profile , but Elle’s collection of awesome profile is most often the files i use.

If you want to scale in linear space, do it before converting to sRGB :wink:.

The ‘geometry’ format has all kinds of special characters to resize to a bounding box , smallest size , longest size , contain, fill etc…

More recent versions (V7 + ? I’m not sure , not keeping up with V6) can do interesting math things in a oneliner .

From bash you can also use imagemagick to do the calculations and print them to an env var and use them in next commands. This can also be done with windows batch files but the syntax is hard to remember for me :wink:(something with the FOR command and a special / option to it ).

In more recent versions you can set an internal imagemagick variable with the -define syntax , and then use the set variable later in the same commandline.

In the -define you can do calculations with the %fx operator , even ternary conditions. Then use the output later.

From the top of my head , it was something like this :
magick inputfile.tif -define option:myvar "%fx [w-5]" -define option:myvarheight "%fx [y-10]" -some-random-other-options -filter lanczos -distort resize "%myvar%x%myvarheight%" outputfile.jpg

But I’m typing this from head on my phone , so consider it as general idea and you have to Google the specifics :).

In other words, can it perform math?

IM v7 can do math within the -resize operation. See my reply in the IM forum

However, IM v6 can’t do math within the -resize operation. For that, you need to do the calculation separately, putting the result in an environment variable, and use that within -resize.

Just for completeness, @jorismak’s example could be:

magick in.tiff -set option:myvar "%[fx:w-5]" -set option:myvarheight "%[fx:h-10]" -distort resize "%[myvar]x%[myvarheight]" out.jpg
1 Like

Ok, If all of you want a story of how stupid Linux is, here it goes.
I’m on Mint 20.3, still using Ubuntu 20.04. So that is ImageMagick v6.something
I download the v7 appimage and it doesn’t work.
I find instructions for downloading v7 on Ubuntu 20.04 from source and they all point to a link that no longer exists.
I eventually work out how to download and install v7 from source using github only to get the message:

convert: error while loading shared libraries: libMagickCore-7.Q16HDRI.so.10: cannot open shared object file: No such file or directory

Feck this, I think, I’ll just stick with v6. I delete v7, then try to my old convert command, but get the same error. Now I’m really stuck. I decide to uninstall then reinstall ImageMagick using Synaptic. And get the same message. I hunt through the list of imagemagick stuff in Synaptic and find one that says libMagickCore-6.Q16HDRI-6 which looks kind of similar, so on a pure guess I install that. I run my old convert command and it works again. I type convert -version out of curiosity and it now tells me I am running 7.1.0-43!

So, the moral of the story is if you want to install something, spend hours banging your head against instructions that don’t work, get an error message you don’t understand that makes your program unworkable, uninstall everything, re-install the old version, and there you have, your new version will work just perfectly! Simple.

Yes, thanks that’s me. I only just discovered those forums and wondered if it might be a more suitable place. Didn’t know you were there. Will keep the conversation going here if need be so we don’t say the same thing twice.

So as a test I run your command like this:

magick -quiet /Path/'Image Name.tif' -filter Sinc -resize %[fx:w-(%5297%-%1600%)*%10%] /Path/ImageName.jpg

And get the following problem:
bash: syntax error near unexpected token `(’

I’m sorry to hear about your installation problems. I know almost nothing about installing IM on varieties of Linux.

I type convert -version out of curiosity and it now tells me I am running 7.1.0-43!

That sounds promising. However, running convert will give you IM v6 syntax. This is provided for backwards compatibility. If you can run magick, you get v7 syntax, and can use %[fx:...] expressions in -resize operations, and other good stuff.

You may find that convert and magick are symlinks to the same executable file. The same applies, because the program will examine arg[0] to determine how it was executed.

I only just discovered those forums and wondered if it might be a more suitable place. Didn’t know you were there.

I’m happy to answer questions here or there. IM developers read the official IM forum, so that is the place to report bugs.

I showed you a Windows command, with Windows environment variables. Bash works differently. Try this (with no env variables):

magick -quiet /Path/'Image Name.tif' -filter Sinc -resize "%[fx:w-(5297-1600)*0.1]" /Path/ImageName.jpg

EDIT: I forgot to say that…

bash: syntax error near unexpected token `(’

… comes from the fact that “(” is a special character in bash, so it needs to be escaped or quoted:

%[fx:w-\(5297-1600\)*0.1]

"%[fx:w-(5297-1600)*0.1]"
1 Like

Ah, i guessed -define wrong… i was close though :wink:

It works beautifully, thanks so much!
One final question. When I change fx:w to fx:h in order to downsize by the height, it upsizes instead. What do I need to change to get height to work the same way?

-resize” takes two parameters, for width and height, separated by “x”. Only one parameter is required, and the “x” can be omitted if there is no height. So:

-resize 30x40” specifies the width and height

-resize 30” or “-resize 30x” specifies just the width

-resize x40” specifies just the height

So you can specify just the height by “-resize x%[fx:h-(5297-1600)*0.1]”. Note the added “x” at the start.

1 Like

@Soupy

or check the manual for the geometry syntax, because there’s a lot of good stuff in there to know :wink: (like I said, it defines how to scale to a bounding box, with aspect ratio, without aspect ratio, minimum size, maximum size, by long side, by short side, etc…).

As @jorismak says, see ImageMagick – Command-line Processing

@jorismak

I did read that, trying a few variants. When they failed, I came here. At first I left the x out. Then I put it in the wrong place, not knowing how to properly combine it with the fx formula. What is obvious to guys with an IT degree and/or years of experience is not necessarily obvious to those without :wink: