Converting anything to RGB correctly

Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
Albert25
Posts: 19
Joined: 2010-06-19T03:57:24-07:00
Authentication code: 8675308

Converting anything to RGB correctly

Post by Albert25 »

I have all sorts of images (CMYK, AdobeRGB, RGB, with and without profiles). I need to convert them all to RGB.

First, I just addressed the CMYK problem, and did this:

Code: Select all

convert -colorspace RGB -resize $size "$f" "photos/$name-$size.jpg"
However, if the image has a profile, I understand I would get better results if I used it.

(also, if the image is already in RGB, is it correct to assume that "-colorspace RGB" will do nothing?)

Then I encountered AdobeRGB images, for which it seems "-colorspace RGB" doesn't help, and I need to use the embedded profile.
(Is there always an embedded profile in AdobeRGB? If not, how can I find out if the image is sRGB or AdobeRGB?)

It seems i can find out if there is a profile with something like

Code: Select all

if convert "$file" "$profile" 2>/dev/null ; then
    # convert using the profile
else
    # no profile, so convert without
fi
Now what is the correct conversion? I am quite confused with the contradictory information I find about the use of profiles in the convert command, and would like to make sure that my script will do the right thing.

For example, the documentation says
...then given two profile conversions is a bad idea. For example
convert cmyk_image.jpg -profile "CMYK.icc" -profile "RGB.icc" output_image.jpg
Will result in a CMYK -> CMYK -> RGB conversion
And numerous examples on the web suggest different things, also changing the order of the options (sometimes the -profile and/or -colorspace options are before the input file, sometimes between the input and the output).

Then I wonder if I need an output profile at all. If I do -colorspace RGB, is there any point in embedding an RGB profile in the output file?

Thanks for any clarifications you have to offer.
Drarakel
Posts: 547
Joined: 2010-04-07T12:36:59-07:00
Authentication code: 8675308

Re: Converting anything to RGB correctly

Post by Drarakel »

Albert25 wrote:also, if the image is already in RGB, is it correct to assume that "-colorspace RGB" will do nothing?
Yes.
Albert25 wrote:Is there always an embedded profile in AdobeRGB? If not, how can I find out if the image is sRGB or AdobeRGB?
Well, the profile should be embedded (if it's not sRGB). And with AdobeRGB files, it almost always is, I would say.

Sometimes, profiles are not embedded and there is only a textual reference in the metadata (e.g. the Photoshop profile). So, if you want to be sure, use "identify -verbose" on the file (or even something like exiftool). If ImageMagick shows that an ICC profile is embedded, use that. If not and you discover a hint to the profile in the metadata, try to use that. (Of course you have to obtain the color profile from somewhere else in this case and you have to specify it manually at the commandline.)
But be careful as sometimes a 'hint' in the metadata is false or was not updated during earlier conversions of the file.
If there are false colors in the image or if there is no embedded color profile, and also no remark in the metadata, then it's the fault of the person that created/sent that file..
In some cases, e.g. when the image looks under-saturated, one is able to say: 'That might be AdobeRGB, I'll try to use that profile and see if it looks correct then.' But that can't be a general approach. :wink:
Albert25 wrote:Now what is the correct conversion?
I think, the documentation says it quite well. (OK, for me, when I started with color profiles, that topic was confusing for me as well.)
If the profile is embedded, just use a "convert inputfile.jpg -profile outputprofile.icc outputfile.jpg" command.
If it's not embedded, use a "convert inputfile.jpg -profile inputprofile.icc -profile outputprofile.icc outputfile.jpg" command.
By the way: If I have a CMYK picture and there's no embedded profile, I typically use "US Web Coated SWOP" as input color profile.

If you're not sure about embedded color profiles, then add '-strip' (which should delete all metadata) or at least '+profile "icc,icm"' (which deletes 'only' the color profiles) after the inputfile - like that:
convert inputfile.jpg -strip -profile inputprofile.icc -profile outputprofile.icc outputfile.jpg
This is to make sure that only the two specified color profiles are used (and not an additional color profile from the input image if it has one embedded).
Other orders of these options are sometimes possible, but the recommended order is to add these between your input and output image.
If you don't want to embed the output color profile into the output image, you can add another '-strip' (or the +profile variant) - after the conversion with the profiles. So, an example of a conversion of a CMYK image without embedded profile into a sRGB image (and no embedding of the sRGB profile) could look like this:
convert input.jpg -strip -profile USWebCoatedSWOP.icc -profile "sRGB Color Space Profile.icm" -strip output.jpg

Feel free to ask if something remains unclear.
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Converting anything to RGB correctly

Post by snibgo »

You don't say what RGB you want. I suspect you want sRGB. If you are not sure (or don't understand the question), I suggest you read http://www.color.org/iccprofile.xalter and other information linked from that page.

A profile defines the meaning of those three numbers we call RGB or CMY, or four numbers CMYK. If you ignore profiles, you will get incorrect results. See http://www.snibgo.org/improf.htm for an artificially extreme example.

You should never do two colour conversions (because each can lose information), and you never need to. Any profile can be converted to any other one directly.

However, the "-profile" option is needed twice when the input has no profile but you want IM to pretend it has.
snibgo's IM pages: im.snibgo.com
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Converting anything to RGB correctly

Post by snibgo »

I cross-posted with Drarakel.

It is generally safe to strip an sRGB profile, but I normally don't, because it then states the profile and programs don't need to guess.
If you're not sure about embedded color profiles, then add '-strip' ...
This shouldn't normally be needed. When it is, you can extract a profile, then strip all profiles, then re-add the extracted profile, then do the profile conversion.
snibgo's IM pages: im.snibgo.com
Albert25
Posts: 19
Joined: 2010-06-19T03:57:24-07:00
Authentication code: 8675308

Re: Converting anything to RGB correctly

Post by Albert25 »

snibgo wrote:You don't say what RGB you want. I suspect you want sRGB. If you are not sure (or don't understand the question), I suggest you read http://www.color.org/iccprofile.xalter and other information linked from that page.
Indeed I'm unsure about what I really want. I sure do understand the question (and had read the page you link to). But I'm now lost between RGB and sRGB. My inputs can be anything, but the output is for display in web browsers.

I know I need to convert CMYK, which is easy to identify (

Code: Select all

identify -format "%r" | grep CMYK
). The CMYKs I have don't appear to have an embedded profile.

I also need to convert AdobeRGB, which I have found no easy way to identify (in a script. Visually, it's obvious).

I don't understand the difference Imagemagick makes between RGB and sRGB. If I use "-colorspace sRGB", the images come out much too dark. If I use "-profile path/to/sRGB.icm -colorspace sRGB", they look identical to -colorspace RGB, so what's the point of sRGB?

The whole point is to have a script which just "does the right thing", without having to treat images manually. It doesn't need to be perfect, but good enough. (for the people who do it now, the low contrast of AdobeRGB on the web page is good enough; for me, it's not)

I'm thinking of something like this (untested approximate code):

Code: Select all

convert $file $file.icc || rm $file.icc
# if there was no profile, it gave an error so we removed the empty icc file
if [ -f $file.icc ]; then
    convert $file -profile $file.icc -colorspace RGB $outputfile
else
    convert $file -colorspace RGB $outputfile
fi
Does it make sense? If all AdobeRGB files are supposed to have an embedded profile, I guess it should work?
Albert25
Posts: 19
Joined: 2010-06-19T03:57:24-07:00
Authentication code: 8675308

Re: Converting anything to RGB correctly

Post by Albert25 »

Thanks a lot for your help, Drarakel and Snibgo. It did clarify a few things, but unfortunately I'm still lost...

Re-reading Drarakel's message, it seemed that my previous idea of using "convert $file -profile $file.icc -colorspace RGB $outfile" would not work. $file.icc would be treated as an output profile instead of an input profile. So I need to specify an output profile as well.

Then I tried
convert CMYK-image.jpg -strip -profile /path/GenericCMYK.icm -profile /path/sRGB.icm -strip cmyk2srgb-profile-strip-srgb.jpg
The result is not too dark this time. Instead, it has no blacks and looks a bit like AdobeRGB: not enough contrast.
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Converting anything to RGB correctly

Post by snibgo »

... the output is for display in web browsers.
Then I suggest your outputs should be sRGB, with or without an embedded profile.

"-colorspace" is ImageMagick's approximate colour conversion. It is appropriate for rough conversions between RGB and CMY(K), when we don't care about exactnesss. I don't think it should ever be used with a "-profile" conversion.
I don't understand the difference Imagemagick makes between RGB and sRGB.
sRGB is a particular form of RGB. Saying an image is "RGB" merely defines the meaning of the three channels. Saying it is "sRGB" goes further, specifying the meaning of the numbers, which can be checked on calibrated measuring equipment. To complicate matters, there are different forms of sRGB for different purposes. See http://www.color.org/ for details.

For images that have an embedded profile (CMYK, AdodeRGB or anything else):

Code: Select all

convert infile.xxx -profile sRGB.icm out.yyy
For RGB images that have no profile, you might assume they are sRGB, so no need to convert them.

For CMY or CMYK images that have no profile, I don't know of an automated solution that will always work well. Drarakel's suggestion:
By the way: If I have a CMYK picture and there's no embedded profile, I typically use "US Web Coated SWOP" as input color profile.
may be as good as any other. ("Web" here refers to a printing process, not the World Wide Web.)
snibgo's IM pages: im.snibgo.com
Drarakel
Posts: 547
Joined: 2010-04-07T12:36:59-07:00
Authentication code: 8675308

Re: Converting anything to RGB correctly

Post by Drarakel »

snibgo wrote:
If you're not sure about embedded color profiles, then add '-strip' ...
This shouldn't normally be needed.
Ideally, it shouldn't be needed. Sometimes (sadly) it is needed.
For example, the usage of embedded profiles in PSD files was not always reliable. (Maybe it's better now?) It's still recommended that way in the paragraph about PSD.
And sometimes, embedded profiles are outright wrong. (Yes, that happens.)

@Albert25:
You might 'miss' a few files with an automated attempt. Nonetheless, in most cases you should get good results with a script like yours (with a few tweaks).
Albert25 wrote:if [ -f $file.icc ]; then
convert $file -profile $file.icc -colorspace RGB $outputfile
I think, you already know now, but just to make sure:
You should change the second line to "convert $file -profile sRGB.icm $outputfile" here.
Albert25 wrote: else
convert $file -colorspace RGB $outputfile
Here, you could check the colorspace (RGB or CMYK). If it's CMYK (without embedded profile), then I would specify a generic CMYK profile (for me, it's mostly US Web Coated SWOP) as source and the sRGB profile as destination. If it's RGB (without embedded profile), then do nothing (take directly $file).
It's possible that you assign a 'false' CMYK profile that way - but what should you do if the 'correct' profile isn't present in the file anymore? For the most files, the differences between the various CMYK profiles won't be thaat big. And I never experienced a real-life-case where the conversion with '-colorspace RGB' was better than the generic conversion with profiles.
Albert25 wrote:Then I tried
convert CMYK-image.jpg -strip -profile /path/GenericCMYK.icm -profile /path/sRGB.icm -strip cmyk2srgb-profile-strip-srgb.jpg
Should be ok.
You could post a input file - or at least the info from "identify -verbose". Then we might say more..
Albert25
Posts: 19
Joined: 2010-06-19T03:57:24-07:00
Authentication code: 8675308

Re: Converting anything to RGB correctly

Post by Albert25 »

Yes, for CMYK, specifying 2 profiles seems to work. (The CMYK files I have don't have a profile). Actually both this:

Code: Select all

convert $f -profile $cmyk_icc -profile $srgb_icc output.jpg
and this

Code: Select all

convert $f -colorspace RGB output.jpg
give acceptable images.

The problem now is that they are different, and I don't know which one is right. Maybe I would need a few test cmyk images to compare results. But then maybe it will only tell me how to best convert that particular picture, and not tell me anything about some random cmyk without an embedded profile ...

Anyway, what doesn't work is "convert $f -colorspace sRGB output.jpg" which gives an image that is much too dark.
Albert25
Posts: 19
Joined: 2010-06-19T03:57:24-07:00
Authentication code: 8675308

Re: Converting anything to RGB correctly

Post by Albert25 »

I uploaded one of my originals and the various conversions here: http://freneticfilms.ch/temp/cmyk/
Firefox displays the original exactly like the simple -colorspace RGB conversion (but of course IE doesn't display it at all, which is why I'm here, bothering you all for help learning this stuf).

Thanks a lot to both of you for your great help.
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Converting anything to RGB correctly

Post by snibgo »

Firefox displays the original exactly like the simple -colorspace RGB conversion
It does. We might conclude that Firefox (in the absence of an embedded profile) uses the same conversion method.

Personally, I prefer NE-cmyk_icc-srgb_icc.jpg, which has less green cast, so the blue sky, face and reflected face appear more natural. But I have no other reason for supposing it is a more accurate conversion.
snibgo's IM pages: im.snibgo.com
Albert25
Posts: 19
Joined: 2010-06-19T03:57:24-07:00
Authentication code: 8675308

Re: Converting anything to RGB correctly

Post by Albert25 »

Yes, it does change the colors, and also the brightness and contrast. Using a different cmyk profile also changes the brightness and contrast. I tried USWebCoatedSWOP and USWebUncoated. I will have to go watch the movie to know which is the "correct" conversion.

Anyway, here is the temporary script I came up with for now. It also improves the one AdobeRGB I have right now, even though the result still lacks some contrast and has no full blacks. But that seems to be a problem with the original, not the conversion. For the curious, I added the last tests to http://freneticfilms.ch/temp/cmyk/ .

Code: Select all

#!/bin/bash

## convert cmyk or adobergb to sRGB.jpg

cmyk=/docs/photos/icc/CMYK/USWebCoatedSWOP.icc
#USWebCoatedSWOP.icc
#USWebUncoated.icc
srgb=/usr/share/ImageMagick-6.5.7/config/sRGB.icm

in=$1

if [ ! -f "$in" ]; then
	echo "Usage: $0 INPUTFILE"
	exit 1
fi

dir=$(dirname "$in")
name=$(basename "$in")
base=${name%.*}

profile="$dir/$base.icc"
out="$dir/$base-new-srgb.jpg"

# extract color profile if present

convert "$in" "$profile" 2>/dev/null

if [ -s "$profile" ]; then
	# we have a profile, so we use that
	echo Using embedded profile
	convert "$in" -profile "$profile" -profile "$srgb" +profile '*' "$out"
else
	if identify -format "%r" "$in" | grep CMYK >/dev/null ; then
		# CMYK file without embedded profile
		echo Generic cmyk conversion
		convert "$in" -profile "$cmyk" -profile "$srgb"  +profile '*' "$out"
		# alternative would be
		#convert "$in" -colorspace RGB "$out"
	else
		# No profile and not cmyk. Probably already in RGB. Do nothing
		echo "Nothing to convert for $in"
	fi
fi

rm "$profile"
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Converting anything to RGB correctly

Post by snibgo »

The cinematographer may have wanted that green cast, of course, and could be upset if you remove it!
convert "$in" "$profile" 2>/dev/null

if [ -s "$profile" ]; then
# we have a profile, so we use that
echo Using embedded profile
convert "$in" -profile "$profile" -profile "$srgb" +profile '*' "$out"
Not quite. Your second convert contains two "-profile" options. The first would convert the image to "$profile". But it is already in that profile, so the command converts from one profile into the same profile. I think this is harmless (lossless), but it certainly takes time.

You might either remove -profile "$profile", or precede it with +profile '*'.
snibgo's IM pages: im.snibgo.com
Drarakel
Posts: 547
Joined: 2010-04-07T12:36:59-07:00
Authentication code: 8675308

Re: Converting anything to RGB correctly

Post by Drarakel »

snibgo wrote:I think this is harmless (lossless)
Perhaps that's not always the case with CMYK - so you really should change that line @Albert25

Apart from that, your conversions look fine. I would just take that and be happy. :)
But since you still seem to be unsure about the result..
a) You could of course experiment some more with the conversions. There are different rendering intents and for example (as snibgo indicated) there are also different versions of the sRGB profile.
b) You could compare the sRGB conversions with the thumbnails of your source files. All three files contain a RGB thumbnail (from Photoshop). I never thought of doing something like that and the thumbnails are really small, but, well, it could give you hints that the process of the conversions is ok (better than the '-colorspace RGB' conversions).
c) You could try to find the real originals (from where your source files were created). As these are movie stills, it's not that difficult. Try these. (Link deleted)
(I would have thought, that Frenetic Films would already get the good files. :wink:)
You will find that your current conversion results resemble the assumed originals pretty well (in lo-res of course). In one case (the 'NE-TE-RETOURNE-PAS-11-640' file), the result is darker (compared to '1165-NeTeRetournePas_11.jpg'). That might be due to a falsely used source color profile. But (as you suggested) it's more likely that the problem is already in the source file.
Last edited by Drarakel on 2010-09-25T23:48:15-07:00, edited 1 time in total.
Albert25
Posts: 19
Joined: 2010-06-19T03:57:24-07:00
Authentication code: 8675308

Re: Converting anything to RGB correctly

Post by Albert25 »

You might either remove -profile "$profile", or precede it with +profile '*'.
That's the part that was both quite clear in the documentation, and also clearly explained in this thread. I somehow still managed to make that mistake. Must have been really too late for me last night...
You could compare the sRGB conversions with the thumbnails of your source files
Thank you. I never thought of checking that. Could be a good hint indeed.
You could try to find the real originals (from where your source files were created). As these are movie stills, it's not that difficult. [...] (I would have thought, that Frenetic Films would already get the good files.
You may be surprised how messy the whole thing is. The material comes from all sorts of producers (most of which have no clue at all about graphic formats) or from graphic designers (some of which don't have much of a clue either). The original photographers delivered their material many months before, and are working on other projects. Between the photographer or cinematographer and the final distributor in a small country, nobody knows through how many people and which processes the pictures have gone. In the end, the distributor has just a big mess of files, which I hope to help them get on the new web site with as little work as possible...

(and the situation with teasers and trailers is much worse than with the stills)

For now, I will just correct the double-profile problem, and we will see how it goes in practice.
Post Reply