# Determine which of two ImageMagick .TXT images is more saturated

You have two images (64x64 pixels each):

Your program must take the file names of each of them as command line arguments and determine which has more average saturation among their pixels.

The images are in ImageMagick .txt format. You can download and convert these images using convert pic.png pic.txt or download the raw text (saturated, desaturated)

Ignore the first line of the file (required).

Solutions in Assembly get 50% of their characters for free. Brainfuck, whitespace, and close variants, get 25% of their characters for free. (e.g. if it takes 200 characters in Brainfuck; mark it as 200-50=150.)

Describe your output. It could be the name of the more saturated image; the index of it (0 for first, 1 for second); true for the first, false for the second, etc. Just let us know.

It should be able to take either the saturated or desaturated image first, and accurately report the more saturated (test both ways). The filenames shouldn't be considered when evaluating saturation (e.g. no if filename contains 'desaturated'...)

Shortest answer wins. Happy coding :-)

• What a hideous-looking input file format. Is it documented anywhere? – Peter Taylor Jan 6 '13 at 22:25
• @PeterTaylor, indeed! .txt image documentation – Brigand Jan 6 '13 at 22:30
• Is this possible in Brainfuck? :P – beary605 Jan 6 '13 at 23:36
• How many of the 52 possible colour spaces must be supported? What bit depths must be supported? How should (partially) transparent pixels be treated for the purposes of averaging? – Peter Taylor Jan 7 '13 at 13:31
• How will you know that the saturation values are correctly computed? – DavidC Jan 7 '13 at 14:02

## J (9694 92)

echo/:(+/@:(m%(m=.>./)-<./)"1@:>@:(".&.>)@:((': ($$.*?$$)';,1)&rxall)@:(1!:1)@:<)&.>2}.ARGV


Takes input from the command line as .txt files. It can take any number of files, and outputs a list of indices from saturated to unsaturated, i.e.:

$jconsole saturated.j saturated.txt desaturated.txt 0 1$ jconsole saturated.j desaturated.txt saturated.txt
1 0


I've simplified the normal formula a bit: it does not bother to normalize the RGB values to [0..1], it uses the sum of the saturation per pixel rather than the average, and it actually calculates the inverse of the saturation and then sorts up. As long as the images are the same size (which they are), this does not affect the sort order which is what it's about.

Explanation:

• 2}.ARGV: the command line minus its first two elements
• &.>: for each of these, do:
• (1!:1)@:<: read file
• ((': ($$.*?$$)';,1)&rxall): use a regex to match the pixel values
• (".&.>): execute each match as J code. (1,2,3) becomes the list 1 2 3 so now we have the pixel values.
• >: make a matrix from the list of lists
• "1: operate on the rows of the matrix
• (m%(m=.>./)-<./): MAX / (MAX - MIN), the inverse of the saturation
• +/: sum
• /:: sort up, so that the images are sorted in S^(-1) ascending, which gives the same order as S descending.
• echo: output the list
• Impressive! Nice explanation, too. – Brigand Jan 6 '13 at 21:11

## bash etc. and Image Magick (136 chars)

for x in "$@";do convert "$x" -colorspace HSL -channel G -separate -scale 1x1 t.txt
echo sed "1d;s%.*#$$..$$.*%\1%" t.txt $x;done|sort  The way I see it, the easiest way to deal with the complexities of the Image Magick file format is to let Image Magick do it. t.txt seems to be the shortest possible filename which guarantees the correct output file format. The first 4 " could arguably be removed, but that would decrease robustness in the face of filenames with spaces in. Sample output: $ ./cmpsat.sh img-sat.txt img-desat.txt rose:
24 img-desat.txt
69 rose:
FE img-sat.txt


## Mathematica 92 215

Edit

To work directly with the Magick files I had to make substantial revisions to my first try.

Filenames

Stored as variables, x, y.

x = "http://pastebin.com/raw.php?i=5f3B4uxP";
y = "http://pastebin.com/raw.php?i=VdjDm9HK";


The following routine sorts image files by average saturation (least to greatest). (Spaces added for readability.)

i = Image; d = DigitCharacter;
f[t_] := {Mean[Flatten[ImageData[ColorConvert[i[i[Partition[(StringCases[URLFetch[t],
"rgb(" ~~ a : d .. ~~ "," ~~ b : d .. ~~ "," ~~c : d .. ~~ ")" :> ToExpression
/@ {a, b, c}])/255., 64]]], "RGB" -> "HSB"]], 1][[All, 2]]], t}


Usage

Sort@{f[x], f[y]}


Output (saturation value, followed by filename).

{{0.229977, "http://pastebin.com/raw.php?i=VdjDm9HK"},
{0.958346, "http://pastebin.com/raw.php?i=5f3B4uxP"}}

Explanation

URLFetch[x] fetches the Magick textfile, the name of which is stored in x

StringCases[URLFetch[t], "rgb(" ~~ a : d .. ~~ "," ~~ b : d .. ~~ "," ~~c : d .. ~~ ")" :> ToExpression /@ {a, b, c}])/255., 64]]], "RGB" -> "HSB"] finds the RGB values and, along with Partition converts them to the format Mathematica expects to find RGB files in.

ColorConvert converts to Hue-Saturation-Brightness values. Mean and [[All,2]] find the mean saturation values for the file.

• I think the OP is asking to get the input as a *.txt file (in ImageMagik format) and not in png format. it isn't very clear, though – Dr. belisarius Jan 6 '13 at 20:00
• here in 79 chars f={a,b};Sort[{Mean@Mean[ImageData@ColorConvert[Import@#,"HSB"]][[;;,2]],#}&/@f] – Dr. belisarius Jan 6 '13 at 20:34
• I was wondering about the formatting issue myself. As for your code, I'm puzzled why the double use of Mean, but I'll look more closely. – DavidC Jan 6 '13 at 20:56
• Mean@Mean is equivalent to Mean@Flatten[...,1] but shorter – Dr. belisarius Jan 6 '13 at 20:58
• @FakeRainBrigand This version uses the .txt files. – DavidC Jan 10 '13 at 15:28

## Brainf**k, 117 - 25% = 87.75

Requires an interpreter with 8-bit wrapping cells (this is the most common type).

>+[,<++++[->--------<]>[>+<]++++[->++++++++<]>]>>
>+[,<++++[->--------<]>[>+<]++++[->++++++++<]>]>
[-<<<[-]>>>]<<<[.]


Just input the text render of the first image and the second image. Make sure the files end with the NUL character (ASCII value 0). If the first image is larger, it will output how much larger it is than the second one (in the ASCII value). If the second image is larger, nothing will be printed.