[Question]
  [
Being a big fan of the Rubik's cube and of cool art, I've been working on combining the two together to do some really cool stuff. Basically solving miniature Rubik's cubes to form rudimentary pixels in the formation of Rubik's cube art. Examples of such art can be seen via this link: <http://google.com/search?q=rubik%27s+cube+art>
Now, the purpose of this Code Golf is to create code that accepts an image as input, and then converts it in the following manner:
The image is initially reduced to web-safe grayscale colors. The reason behind this is because we need to isolate the web-safe grayscale palette (i.e. 000000, 333333, 666666, 999999, CCCCCC, and FFFFFF). An algorithm on the colorimetric method of converting to grayscale is available at: <http://en.wikipedia.org/wiki/Grayscale#Colorimetric_.28luminance-preserving.29_conversion_to_grayscale>, should you wish to use that as inspiration.
One would then render out the grayscale to the appropriate colors. To break it down quickly:
000000 will refer to Rubik's blue, 333333 will refer to Rubik's red, 666666 will refer to Rubik's green, 999999 will refer to Rubik's orange, CCCCCC will refer to Rubik's yellow, and FFFFFF will refer to Rubik's white.
I would rather that your resulting code can render from the photo's palette straight to Rubik's colors. The two-stage method from converting to web-safe grayscale and then to the corresponding Rubik's palette is just to give you an idea on the logic behind the process, but if it is easier for you to do this, by all means do so.
The actual RGB values for the Rubik's palette must correspond to the following: 
* Red: #C41E3A
* Green: #009E60
* Blue: #0051BA
* Orange: #FF5800
* Yellow: #FFD500
* White: #FFFFFF
To give you an example, I have cropped Abraham Lincoln's head from the following picture: ![enter image description here](https://i.stack.imgur.com/Ei856.png), and rendered the algorithm to produce the following: 
![enter image description here](https://i.stack.imgur.com/TkvQd.png)
The grid is there so that you can see how each individual miniature Rubik's cube would have to be configured to make up the image. The true size of the resulting image is 45 pixels by 45 pixels, meaning (45/3) \* (45/3) = 15 \* 15 = 225 miniature Rubik's cubes would be used to make this image. I am not expecting you to present the resulting image with a grid as I have.
So this is what's required:
1. The image to be processed by this algorithm must be x pixels wide by y pixels high, such that x and y are multiples of 3. This is to aid with the ease of rendering as part of a Rubik's cube mosaic. If your image is quite large, reducing it to something around the 45 x 45 to 75 x 75 or thereabouts in dimensions prior to processing is advised. Bear in mind, this resizing component is OPTIONAL.
2. The image needs to be converted to the sextacolored Rubik's cube palette to create the mosaic.
3. The resulting image needs to be a valid graphic file after processing. To prove your code works, run it against an image of one of the presidents of the United States of America, or a well known Hollywood celebrity. I have already used Abraham Lincoln in my example, so this president can no longer be used. Ensure that you provide the language you have used, the byte count as well as the president/celebrity used to test your code, including before and after shots...
4. Each entry must have a unique president/celebrity as their test case. I will not accept duplicates. This will ensure that duplicate results are not used to test different code entries. It's all very well to say that your code works, it's another thing to prove it.
5. Shortest code wins.
I'm changing this to a popularity contest... I'd rather see who can do this without having to compete on byte count... So I'll award this along with a bounty after the 28th of February, 2014.
  
[Answer]
# Imagemagick (108)
Version: ImageMagick 6.8.7-7 Q16 x86\_64 2013-11-27
The following call:
```
$ convert -resize 75x75 -fx "q=p.intensity;q<1/6?#0051BA:q<2/6?#C41E3A:q<3/6?#009e60:q<4/6?#ff5800:q<5/6?#FFD500:#FFF" input output
```
where `input` and `output` have to be modified for the input and output filename.
I only counted the chars between `-resize` and `#FFF"`, if you think this is invalid feel free to comment.
I used Lenna as image (she appeared in a Playboy, and anyone doing that should count as a Hollywood celebrity, right?)
Input:
![Input image](https://i.stack.imgur.com/azjq4.png)
Output:
```
$ convert -resize 75x75 -fx "q=p.intensity;q<1/6?#0051BA:q<2/6?#C41E3A:q<3/6?#009e60:q<4/6?#ff5800:q<5/6?#FFD500:#FFF" Lenna.png LennaRubik.png
```
![Generated image](https://i.stack.imgur.com/lru9H.png)
Output enlarged:
![Enlarged image](https://i.stack.imgur.com/XK33N.png)
Notes: according to the imagemagick docs you cannot have more than one conditional operator in a statement, but the call still seems to work fine, so probably this was fixed and the docs were just not updated.
Running identify on the result image (to show the colors are indeed fine):
```
$ identify -verbose LennaRubik.png
  (...)   
  Colors: 6
  Histogram:
       338: (  0, 81,186) #0051BA srgb(0,81,186)
      1652: (  0,158, 96) #009E60 srgb(0,158,96)
      1187: (196, 30, 58) #C41E3A srgb(196,30,58)
      1674: (255, 88,  0) #FF5800 srgb(255,88,0)
       706: (255,213,  0) #FFD500 srgb(255,213,0)
        68: (255,255,255) #FFFFFF white
  (...)
```
If you think Lenna doesn't count as a proper celebrity, here is Bruce Willis:
![Bruce Original](https://i.stack.imgur.com/jxB78.jpg)
![Bruce Small](https://i.stack.imgur.com/HLnF4.png)
![Bruce Large](https://i.stack.imgur.com/ZcSYa.png)
[Answer]
# Mathematica
We'll work with a square region from a U.S. stamp featuring Greta Garbo.
It will be referred to as `j`.
![j](https://i.stack.imgur.com/U8Kvb.png)
```
f[i_,rs_,m_:True]:=
Module[{(*rs=rastersize-4*)r={0.77,0.12,0.23},gr={0,0.62,0.38},b={0,0.32,0.73},o={1,0.35,0},y={1,0.84,0},w={1,1,1},
c1={r,gr,b,o,y,w},grayGreta,garboColors},
grayGreta=(*Reverse@*)ImageData[ColorQuantize[Rasterize[i,(*ImageResolution \[Rule]15*)RasterSize->rs+1,ImageSize->rs],6]];
garboColors=Union@Flatten[grayGreta,1];
ArrayPlot[grayGreta/.Thread[garboColors-> RGBColor@@@c1],
Mesh->If[m==True,{rs-1,rs-1},None],MeshStyle->Black]]
```
The function f takes 3 parameters:
* `i` which refers to the image
* `rs`, the raster size
* `m`, a boolean variable that states whether Mesh lines should be used. (The default setting is True).
---
Using raster sizes of 15, 30, 45, and 75:
```
GraphicsGrid[{{f[j, 15], f[j, 30]}, {f[j, 45], f[j, 75]}}, ImageSize -> 800]
```
![4 garbos](https://i.stack.imgur.com/uI8oo.png)
I can't imagine anyone making a Rubrik's cube with so many pieces! Interesting exercise nonetheless.
---
## Playing around with colors
This is from an earlier entry. The code is slightly different. `Graphics` is used instead of `ArrayPlot`. Also, we use the full stamp even though it is not square.
There are 6!=720 permutations of the Rubrik cube colors.
The following displays the center image of the upper row (set 6 images below).
When the grayscale values are arranged from darkest to lightest, the colors are {r,gr,b,o,y,w}. Other variations nonetheless work.
`i` is the original image in grayscale.
```
Graphics[Raster[(g=Reverse@ImageData[ColorQuantize[Rasterize[i,RasterSize->75],6]])
/.Thread[Union@Flatten[g,1]-> {{7,1,2},{0,6,4},{0,3,7},{10,4,0},{10,8,0},{10,10,10}}/10]]]
```
---
`i` is the original grayscale image of the full Greta Garbo stamp.
`Rasterize[garbo,RasterSize->75` rasterizes the image into a 75 by 75 array.
`ColorQuantize[<>, 6]` reduces the grayscale values to a set of 6.
`ImageData` retrieves the data array from the image; it comes upside-down.
`Reverse` flips the data array, hence the picture, right-side up.
`garboColors` are the 6 grayscale values in the quantized image.
`Graphics[Raster` displays the final image.
`rubrikColors` are RGB values of the 6 Rubrik cube colors.
Various color permutations of Red, Green, Blue, Orange, Yellow, and White are given.
```
r={0.77,0.12,0.23};gr={0,0.62,0.38};b={0,0.32,0.73};o={1,0.35,0};y={1,0.84,0};w={1,1,1};
c1={r,gr,b,o,y,w};
c2={r,b,gr,o,y,w};
c3={b,r,gr,o,y,w};
c4={gr,b,r,o,y,w};
c5={b,r,gr,y,o,w};
```
And the code:
```
grayGreta=Reverse@ImageData[ColorQuantize[Rasterize[i,RasterSize->75],6]];
garboColors=Union@Flatten[grayGreta,1];
Grid[{{i,
Graphics[Raster[grayGreta/.Thread[garboColors-> c1]]],
Graphics[Raster[grayGreta/.Thread[garboColors-> c2]]]},
{Graphics[Raster[grayGreta/.Thread[garboColors-> c3]]],
Graphics[Raster[grayGreta/.Thread[garboColors-> c4]]],
Graphics[Raster[grayGreta/.Thread[garboColors-> c5]]]}}]
```
![garbos](https://i.stack.imgur.com/dwRgh.png)
---
## Garbos Galore
Here are 72 (of the 720) images of Greta Garbo that use the 6 Rubrik cube colors. Some images work better than others, don't you think?
```
GraphicsGrid@Partition[(Graphics[Raster[grayGreta /. Thread[garboColors -> #]]] & 
/@ Take[Permutations[{r, gr, b, o, y, w}, {6}], 72]), 12]
```
![garbos galore](https://i.stack.imgur.com/fvqAa.jpg)
[Answer]
# Smalltalk (Smalltalk/X), 289 139\*
input: i; output: r
```
r:=i magnifiedTo:75@75.
r colorMapProcessing:[:c||b|b:=c brightness.Color rgbValue:(#(16r0051BA 16rC41E3A 16r009e60 16rff5800 16rFFD500 16rFFFFFF)at:(b*6)ceiling)]
```
input:
![enter image description here](https://i.stack.imgur.com/w28Wu.jpg)
output:
![enter image description here](https://i.stack.imgur.com/GOFKK.png)
enlarged:
![enter image description here](https://i.stack.imgur.com/FLsDW.png)
(for all youngsters: this is NOT Madonna ;-)
[\*] I have not counted the magnification to 75x75 (the first line) - could have used an already resized as input. Hope that is ok with you.
[Answer]
## Postscript, and TRUE Rubik colors! ;-)
Well, this solution is a bit of off-topic here, as it's restricted to somewhat highly specialized sphere. But after much frustration with e.g. "weird numbers question" (being unable to produce something practically working) I decided to publish something and so pulled this out of my pile of half-finished scribbles and made it presentable.
The solution exploits the fact, that 1st revision of this question defines required colors by link to a site, which clearly states, that Pantone(R) colors are to be used, and RGB colors are approximations only. Then I thought, why would I do approximations, when I can do genuine color? -:)
```
10 dict begin
/Size 75 def
/Names  [(PMS 012C) (PMS 021C) (PMS 347C)   (PMS 200C)    (PMS 293C)   ] def
/Colors [[0 .16 1 0][0 .65 1 0][1 0 .39 .38][0 .9 .72 .28][1 .56 0 .27]] def
<</PageSize [Size dup]>> setpagedevice
Size dup scale
true setoverprint
(%stdin) (r) file 100 string readline pop 
(r) file <</CloseSource true>>/DCTDecode filter
0 1000000 string 
dup <</CloseTarget true>>/NullEncode filter 
{
    3 index 3 string readstring
    {
        4 -1 roll 1 add 4 1 roll
        {} forall
        0.11 mul exch 0.59 mul add exch 0.3 mul add cvi
        1 index exch write
    } {pop exit} ifelse
} loop
closefile
0 3 -1 roll getinterval
exch closefile
/data exch def
/n data length sqrt cvi def
1 1 Names length {
    /N exch def
    { 
        dup N Names length 1 add div gt 
            {N 1 add Names length 1 add div gt 
                {1} {0} ifelse} 
            {pop 1} 
        ifelse
    } settransfer
    [/Separation Names N 1 sub get /DeviceCMYK {
        Colors N 1 sub get 
        { 1 index mul exch } forall pop
    }] setcolorspace
    <<
        /ImageType        1
        /Width            n
        /Height           n
        /ImageMatrix      [n 0 0 n neg 0 n]
        /BitsPerComponent 8
        /Decode           [0 1]
        /DataSource       data
    >> image
} for
showpage
end
```
This code is to be saved as e.g. `rubik.ps` and then fed to Ghostscript with usual incantation:
```
gs -q -sDEVICE=psdcmyk -o out.psd rubik.ps
```
It then waits you on the next line, for input of JPG file name e.g. 
```
kelly.jpg
```
and, if all goes well, saves the output to `out.psd` file.
Input must be square RGB JPEG (any size), output is PSD with spot color channels. You'll need Photoshop to view the file. Changing GS device from `psdcmyk` to anything else will produce nothing usable. JPEG as input - because postscript interpreter can decode data stream from it directly. Square shape - because the program relies on `sqrt` of string length to find width (and height) of the image.
First lines define output image size (can be changed from default 75) and the color palette (colors and their number can be changed too). Anything else is not hard-coded, I think.
What's going on? Stream of RGB triplets is converted on the fly to the string of grayscale values (with simple formula), usual 8-bit contone image dictionary is built and used to paint 5 identical images on top of each other in 5 `Separation` color spaces. The trick is to apply transfer functions before each invocation of `image` operator. E.g. for yellow paint this function returns 0 for input values in 0.167 .. 0.333 range only, and 1 otherwise. 
Input:
![enter image description here](https://i.stack.imgur.com/OgZpc.jpg)
Screenshot of output 75x75 open in Photoshop, enlarged 800%:
![enter image description here](https://i.stack.imgur.com/WDULv.png)
And Photoshop channels palette:
![enter image description here](https://i.stack.imgur.com/zmFrI.png)
[Answer]
# Brainfuck
```
++++[->+[,.----------]<]>>>>---->->++++++++++>>------------>+++>+++>--
--->++++++[->+++++<]---->+[-<+++++++<+++<+++++<+++<+++<++++++<++++++<+
<++>>>>>>>>>]<[<]<<,+[,<++++++>[>++++++[->+++++++<]>+[<<[->]>[<]>-]<<<
->]+<[-[-[-[-[[-].>>>>>>>>.<.<<<<<<-<]>[->>>>>[.<]<<]<]>[-.>>>[>]<<<.<
.[<]<<]<]>[--.+>>>[>]<<.[<].<<]<]>[--.+>>>[>]<.[<].<<]<]>[--...+],,+]
```
This requires a BF interpreter/compiler that has -1 as EOF and that has higher than 8 bit cells IF one of the red pixels are 255. Or else it will stop premature since it won't be able to differ between EOF and value 0xFF. With jitbf you have whatever the machine has as integer size and can do this to force -1 as EOF:
```
jitbf --eof -1 rubiks.bf < angelina.pnm > angelina-rubix.pnm
```
The image file format rendered is the full RGB PNM file (P6), raw as option in Gimp.
It uses the green channel only (which is one of many ways to convert a color image to greyscale). It reduces the value by 43 without reduceing the value below zero to find out which rubiks color to use and have a switch that prints out the correct RBG color that corresponds.
Image of Angelina Jolie from [Hackers (1995)](http://www.imdb.com/title/tt0113243/?ref_=fn_al_tt_1) scaled down to 75x75 and processed with the application:
![Angelina Jolie 75x75 / Fair Use](https://i.stack.imgur.com/1v4Ty.png) ![Angelina Jolie 75x75 in Rubiks cube colors / Fair Use](https://i.stack.imgur.com/6S86B.png) ![Same scaled 6x](https://i.stack.imgur.com/BFHM1.png)
Same, only I used [the original size](http://girlcrushzine.tumblr.com/post/7054073876/remember-angelina-jolie-as-acid-burn-in-hackers):
![Same only not scaled down first / Fair use](https://i.stack.imgur.com/E9TyS.png)
And since I'm psychic here's a president as well:
![Arnold Schwarzenegger CC from Wikipedia](https://i.stack.imgur.com/iXRLf.png)
[Answer]
# C#
```
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
class Program
{
    static void Main(string[] args)
    {
        unchecked
        {
            var t = new[] { 0xFFC41E3A, 0xFF009E60, 0xFF0051BA, 0xFFFF5800, 0xFFFFD500, 0xFFFFFFFF }.Select(v => Color.FromArgb((int)v)).ToArray();
            var o = new Bitmap(Bitmap.FromFile(args[1]));
            var m = double.Parse(args[0]);
            var r = Math.Min(m / o.Width, m / o.Height);
            var w = (int)(o.Width * r);
            var h = (int)(o.Height * r);
            o = new Bitmap(o, w - (w % 3), h - (h % 3));
            for (int y = 0; y < o.Height; y++)
                for (int x = 0; x < o.Width; x++)
                    o.SetPixel(x, y, N(o.GetPixel(x, y), t));
            o.Save(args[2], ImageFormat.Png);
        }
    }
    static Color N(Color c, Color[] t)
    {
        return t.OrderBy(v => Math.Abs(W(v) - W(c))).First();
    }
    static double W(Color c)
    {
        return .11 * c.B + .59 * c.G + .30 * c.R;
    }
}
```
You need to run it with 3 parameters:
`foo.exe 75 d:\test.jpg d:\out.png`
Where `75` is max. width/height, `d:\test.jpg` is input file and `d:\out.png` is the output file.
Output for various images in this contest:
![WallyWest](https://i.stack.imgur.com/qbcrg.png)
![SztupY 1](https://i.stack.imgur.com/sRkte.png)
![SztupY 2](https://i.stack.imgur.com/Tncwh.png)
![blabla999](https://i.stack.imgur.com/SejDG.png)
My own celebrity:
![Garth!](https://i.stack.imgur.com/GKlq9.jpg)
Output:
![Garth 75](https://i.stack.imgur.com/SssLt.png) ![Garth 225](https://i.stack.imgur.com/jialg.png)
However, other (larger than 75x75) sizes do result in better images:
![150](https://i.stack.imgur.com/7nPIp.png)
![300](https://i.stack.imgur.com/1fALX.png)
And, if we stick with presidents:
![DubbaYa 294](https://i.stack.imgur.com/Zu2aS.jpg) ![DubbaYa 75](https://i.stack.imgur.com/DT6vH.png) ![DubbaYa 225](https://i.stack.imgur.com/57INM.png)
Since this is no (longer?) codegolf I didn't bother to "minimize" the code too much. Also, since the instructions did not specifically mention the image had to be the same width as height (square) I didn't bother with cropping; I *do*, however, make sure the image is a multiple of 3 pixels wide/high. If you want square images, use square inputs ![:P](https://tweakimg.net/g/s/puh2.gif) Finally; the algorithm is far from optimal.
A few more (since people upvote hot chicks / internet heroes more ![:P](https://tweakimg.net/g/s/puh2.gif) )
![Kari Byron 300](https://i.stack.imgur.com/ttn2q.jpg) ![Kari Byron 75](https://i.stack.imgur.com/q2kWx.png) ![Kari Byron 225](https://i.stack.imgur.com/ffTvT.png)
![The Hoff 300](https://i.stack.imgur.com/lAxDx.jpg) ![The Hoff 75](https://i.stack.imgur.com/Amzwg.png) ![The Hoff 225](https://i.stack.imgur.com/6Mmii.png)
[Answer]
# [Piet](https://www.dangermouse.net/esoteric/piet.html)
[![enter image description here](https://i.stack.imgur.com/IuUZM.png)](https://i.stack.imgur.com/IuUZM.png)
It is presented here with a codel size of 20 for readability's sake. To counter that same aspiration, it has been half-heartedly if not golfed then at least been subject to compacting efforts.
Tested with [npiet](https://www.bertnase.de/npiet/) like so:
```
npiet -q rc.png < infile.ppm > outfile.ppm
```
Assumes the files are of the "plain" RGB variety (P3), i.e. with the image data as numbers in plaintext and not binary. It ignores the maximum colour value and just assumes that it is 255. In the output, every whitespace is a newline.
Looping over each pixel, the following happens:
1. The colours we are to choose from are pushed to stack, lightest first, so that the darkest colours end up on top.
2. The RGB triplet is read in and converted to greyscale. Since floating point mathematics is not built-in nor trivial to implement, integer maths is used: `grey = (red * 299 + green * 587 + blue * 114) / 1000`.
3. The greyscale value is divided by 43, to obtain a number 0..5 (colour index = ci).
4. This number is increased by 1, multiplied by 3 and duplicated on stack. The top value is then decreased by 3, giving us two values on top of stack: `[(ci - 1) * 3] [ci * 3]`.
5. These new values are used with the `roll` instruction, which will - with the parameters given above - bring the desired RGB triplet to the top of the stack. (You can think of it as taking a deck of cards and cutting it so that you hold `ci * 3` cards in your hand, and then taking the top card of that little stack you're holding and putting it down on the pile still on the table, then placing what you hold top of that; repeat this `(ci - 1) * 3` times.)
6. Triplet is output in the usual way.
7. The unused triplets are popped from stack.
8. If at the end, we exit, otherwise we go back to step 1.
Input:
[![enter image description here](https://i.stack.imgur.com/hcK8F.png)](https://i.stack.imgur.com/hcK8F.png)
Output 75x75 (input was scaled before passing it to the program itself):
[![enter image description here](https://i.stack.imgur.com/BkLwb.png)](https://i.stack.imgur.com/BkLwb.png) [![enter image description here](https://i.stack.imgur.com/Islrp.png)](https://i.stack.imgur.com/Islrp.png)
Output very large indeed:
[![enter image description here](https://i.stack.imgur.com/TD9M9.png)](https://i.stack.imgur.com/TD9M9.png)
[Answer]
# Objective-C
I saw this challenge last night and had an ever so slightly confusing time with `-[NSArray indexOfObject:inSortedRange:options:usingComparator:]`, hence the delay.
```
- (UIImage  *)rubiksImage:(UIImage *)inputImg
{
    //Thank you http://stackoverflow.com/a/11687434/1153630 for the greyscale code
    CGRect imageRect = CGRectMake(0, 0, inputImg.size.width, inputImg.size.height);
    int width = imageRect.size.width;
    int height = imageRect.size.height;
    uint32_t *pixels = (uint32_t*)malloc(width * height * sizeof(uint32_t));
    memset(pixels, 0, width * height * sizeof(uint32_t));
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(pixels, width, height, 8, width * sizeof(uint32_t), colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedLast);
    CGContextDrawImage(context, imageRect, [inputImg CGImage]);
    const int RED = 1;
    const int GREEN = 2;
    const int BLUE = 3;
    for (int y = 0; y < height; y++)
    {
        for (int x = 0; x < width; x++)
        {
            uint8_t* rgbaPixel = (uint8_t*)&pixels[y * width + x];
            uint32_t grayPixel = 0.3 * rgbaPixel[RED] + 0.59 * rgbaPixel[GREEN] + 0.11 * rgbaPixel[BLUE];
            NSArray *r = [self rubixColorFromGrey:grayPixel];
            rgbaPixel[RED] = [r[2] integerValue];
            rgbaPixel[GREEN] = [r[1] integerValue];
            rgbaPixel[BLUE] = [r[0] integerValue];
        }
    }
    CGImageRef newCGImage = CGBitmapContextCreateImage(context);
    CGContextRelease(context);
    CGColorSpaceRelease(colorSpace);
    free(pixels);
    UIImage* newUIImage = [UIImage imageWithCGImage:newCGImage];
    CGImageRelease(newCGImage);
    return newUIImage;
}
- (NSArray *)rubixColorFromGrey:(uint32_t)p
{
    NSArray *colors = @[@0, @51, @102, @153, @204, @255];
    NSUInteger index = [colors indexOfObject:@(p)
                               inSortedRange:NSMakeRange(0, colors.count)
                                     options:NSBinarySearchingInsertionIndex | NSBinarySearchingFirstEqual
                             usingComparator:^(id a, id b) {
                                return [a compare:b];
                             }];
    switch (index) {
        case 0:
            return rgb(0, 81, 186);
            break;
        case 1:
            return rgb(196, 30, 58);
            break;
        case 2:
            return rgb(0, 156, 96);
            break;
        case 3:
            return rgb(255, 82, 0);
            break;
        case 4:
            return rgb(255, 213, 0);
            break;
        case 5:
            return rgb(255, 255, 255);
            break;
        default:
            break;
    }
    return colors; //go wild
}
NSArray *rgb(int r, int g, int b)
{
    return @[@(r), @(g), @(b)];
}
```
I ran it on my iPad like so:
```
UIImageView *img = [[UIImageView alloc] initWithImage:[self rubiksImage:[UIImage imageNamed:@"danny.png"]]];
[img setCenter:self.view.center];
[self.view addSubview:img];
```
**Before**
![Danny DeVito Before](https://i.stack.imgur.com/INK6z.jpg)
**After**
![Danny DeVito After](https://i.stack.imgur.com/dADkt.jpg)
  
  
**Before**
![Grace Kelly Before](https://i.stack.imgur.com/ZFzvl.jpg)
**After**
![Grace Kelly After](https://i.stack.imgur.com/jfhjq.png)
[Answer]
# Python
Format: `python rubik.py <input> <max_cubes> <output>`.
Coverts pixel to grayscale using suggested algorithm.
```
import Image, sys
def rubik(x, max_cubes = 25):
    
    img = x
    max_cubes *= 3
    
    if x.size[0] > max_cubes or x.size[1] > max_cubes:
        print "Resizing image...",
        
        if x.size[0] > x.size[1]:
            img = x.resize((max_cubes, int(max_cubes * float(x.size[1]) / x.size[0])), Image.ANTIALIAS)
        else:
            img = x.resize((int((max_cubes * float(x.size[0]) / x.size[1])), max_cubes), Image.ANTIALIAS)
    if x.size[0] % 3 or x.size[1] % 3:
        print "Sizes aren't multiples of 3"
        return
    print "Image resized to %i x %i pixels" % img.size
    out = Image.new('RGB', img.size)
    print "Converting image...",
    for x in xrange(out.size[0]):
        for y in xrange(out.size[1]):
            r, g, b = img.getpixel((x, y))
            if r == g == b == 255:
                out.putpixel((x,y), (255, 255, 255))
            else:
                l = 0.2126 * r + 0.7152 * g + 0.0722 * b
                l /= 255
                out.putpixel((x,y), (
                        (0x00, 0x51, 0xBA),
                        (0xC4, 0x1E, 0x3A),
                        (0x00, 0x9E, 0x60),
                        (0xFF, 0x58, 0x00),
                        (0xFF, 0xD5, 0x00)
                    )[int(5 * (l <= 0.0031308 and 12.92 * l  or 1.055 * l ** (1/2.4) - 0.055))])
    print "Image converted successfully."
    print "Stats:"
    h, v = img.size[0] / 3, img.size[1] / 3
    print "   ", h, "horiz. Rubik cubes"
    print "   ", v, "vert. Rubik cubes"
    print "   ", h * v, "total Rubik cubes"
    
    return out.resize((out.size[0], out.size[1]))
if __name__ == "__main__":
    rubik(Image.open(sys.argv[1]).convert("RGB"), int(sys.argv[2])).save(sys.argv[3])
    
```
Input:
[![Sandro Pertini](https://i.stack.imgur.com/h3E4Z.jpg)](https://i.stack.imgur.com/h3E4Z.jpg)  
(source: [ilmamilio.it](http://www.ilmamilio.it/m/images/images2/Varie/sandropertini.jpg))
Output with `max_cubes = 25`:
![Sandro Pertini, Rubik'd 1](https://i.stack.imgur.com/7G4Jr.png)
Output with `max_cubes = 75`:
![Sandro Pertini, Rubik'd 2](https://i.stack.imgur.com/DYkn8.png)
Output with `max_cubes = 225`:
![Sandro Pertini, Rubik'd 3](https://i.stack.imgur.com/XQh1A.png)
]