I am trying to get the saturation level of an image, to calculate if it is closer to being greyscale or colour. This needs to work on any image file format. I also need to be able to get the other information, including file type, mime type, width, height, and possibly the perceptual hash moments. It also needs to remain the JSON output.
Currently I am using convert image.png json:-
which outputs almost all of the data I need, with the exception of the image saturation. I tried convert image.png -colorspace HSL json:-
, under the assumption that it would change the channels from red, green and blue (and gray) to hue, saturation and lightness, but it remained the former.
When using the RGB colorspace, a greyscale image returns just two channelStatistics, alpha and gray, while a colour image returns alpha, red, green and blue. When using HSL, it returns alpha, red, green and blue for greyscale and colour, in the following format (this is a greyscale example):
[channelStatistics] -> Object
(
[alpha] => stdClass Object
(
[min] => 255
[max] => 255
[mean] => 255
[standardDeviation] => 0
[kurtosis] => 0
[skewness] => 0
)
[red] => stdClass Object
(
[min] => 0
[max] => 0
[mean] => 0
[standardDeviation] => 0
[kurtosis] => 0
[skewness] => 0
)
[green] => stdClass Object
(
[min] => 0
[max] => 0
[mean] => 0
[standardDeviation] => 0
[kurtosis] => 0
[skewness] => 0
)
[blue] => stdClass Object
(
[min] => 20
[max] => 255
[mean] => 230.007
[standardDeviation] => 44.1297
[kurtosis] => 2.21673
[skewness] => -1.80749
)
)
What command would return the information I need? I do not want to alter the original image; it needs to remain untouched. I just need to get these certain details.
When you do
convert input.png -colorspace hsl json:
the output is actually in HSL, except it is, somehwat misleadingly, labelled as Red, Green and Blue.
You can test this by creating an image that is pretty much red but with a little variation in it so that IM can't encode it as a palettised image like this:
convert -size 1000x1000 gradient:"rgb(255,0,0)-rgb(230,10,0)" input.png
Now if you look at the JSON it looks like this - largely fully saturated bright Red
"channelStatistics": {
"red": {
"min": "59110",
"max": "65535",
"mean": "62322.5",
"standardDeviation": "1856.6",
"kurtosis": "-1.19999",
"skewness": "1.52719e-06"
},
"green": {
"min": "0",
"max": "2570",
"mean": "1285",
"standardDeviation": "742.641",
"kurtosis": "-1.19999",
"skewness": "0"
},
"blue": {
"min": "0",
"max": "0",
"mean": "0",
"standardDeviation": "0",
"kurtosis": "0",
"skewness": "0"
}
},
and if you convert to HSL
convert input.png -colorspace hsl json:
it now looks like this:
"channelStatistics": {
"red": {
"min": "0",
"max": "475",
"mean": "229.308",
"standardDeviation": "137.131",
"kurtosis": "-1.19385",
"skewness": "0.071888"
},
"green": {
"min": "65535",
"max": "65535",
"mean": "65535",
"standardDeviation": "0",
"kurtosis": "0",
"skewness": "0"
},
"blue": {
"min": "29555",
"max": "32768",
"mean": "31161.5",
"standardDeviation": "928.298",
"kurtosis": "-1.20001",
"skewness": "1.58408e-08"
}
},
It may be sold as Red, Green and Blue, but actually the "Red" is the Hue which is close to zero, i.e. red, and the "Green" is actually the Saturation and you can see it is fully saturated, and the "Blue" is the Lightness which is mid grey.