IT stuff.

Menu

All RGB colors in one image

I recently started visiting the programming puzzles SE site. To a geek like me, it’s a little paradise: many interesting challenges, many interesting solutions, many like-minded people. Two days ago, there was one particular challenge: make a program to create an image that contains all RGB colors exactly once (and of course the best looking one wins). A very long time ago I made a small screen saver in assembly which grew a colorful coral (I may post that one day, too). I thought something similar would work here and maybe I’ll even get some votes. You can see the very first image right here. The results completely blew my mind, they were absolutely stunning, and of course it was a big success. Then I thought, let’s make a huge image, maybe even a YouTube video from this. But it wasn’t easy because it’s a brutally exponential problem. Two days of non-stop coding and minimum sleeping later, here it is!

Of the four most widespread image formats, the images have to be in PNG format, because it supports lossless compression and all RGB colors. GIF doesn’t work because it only supports at most 256 colors. JPEG doesn’t work because it uses a lossy compression, so some colors are slightly altered. We need to have 100% accuracy to represent all these different colors. BMP’s would be fine but they don’t do any (decent) compression. So all the images you see below are PNG’s, the original, raw files, which were produced by my program. Feel free to count the colors in them .

The first images: 15 bits

Let’s start with some of the first images I made. These contain 15-bit RGB colors, with a resolution of 256×128 (about 32 thousand pixels). (Note: when the number of pixels in an image is a power of 2, then the dimensions of the image must also be powers of 2, but my size choices are not the only ones possible.) Little tweaks in the algorithm lead to somewhat or very different images, there are endless possibilities which I’m sure some other people will find themselves if they try it. These are just a very few samples.

I even made some small animgifs because watching them grow is also beautiful.

A bit bigger: 18 bits

All 18 bit RGB colors fit on a 512×512 image (about 260 thousand pixels). It took tens of minutes to render them with the very first version of my program, now it only takes a few seconds. The bottom three images are used in the YouTube video.

Let’s go to YouTube: 21 bits

Next up: 21 bits, that’s 2048×1024 (about 2 million pixels). I seriously had to work on those. Even with all the optimizations I could think of (yet!), some of these took up to 8 hours to render. Let me show you four different ones, each in an intermediate state and in the final state.

Here’s the most basic one. The colors are very random. It just grows circularly. Looks like a flower, or staring into infinity, or whatever.

This is actually my favorite. It differs from the previous one because the colors are not entirely random, they are sorted by hue. The phrases that come to my mind are rainbow smoke and spilled ink. This is the best one to see in motion.

When you look at the end result, this one looks very much like the first one, only a little bit blurred. What’s very different is how it grows. It uses a different algorithm that makes it look like a coral. The best is when it is 90-95% finished, as shown here.

And finally, a blend between the second and third: ordered by hue, growing like a coral. When you look at the intermediate one, be sure that it’s shown 1:1 and not resized because that looks bad. The end result is just weird.

My best idea about this topic was to create a YouTube video of how each of the above four pictures are created inside the program. I never created many interesting videos before, but I knew that this is going to be a hit. Sadly the images had to be cropped (2048->1920) and I added little black bars on the top and bottom (1024->1080), and of course the video compression alters the colors slightly (and in the case of YouTube, it also introduced some really ugly artifacts). So this is not technically all-RGB imagery anymore, but it’s not the point. The point is that this video looks spectacular! I also wrote a lot of source code to render the video frames, then I used FFMpeg to put it all together. Finally I chose a music from YouTube’s free audio library. Enough talking, watch the video now, and be sure to watch it in HD!

The holy grail: 24 bits

Nowadays, most consumer grade equipment’s and software’s limit is to display 24 bit colors. So naturally this was my final goal as well. It fits on an image with 4096×4096 resolution (about 16 million pixels). (I remember the days when my Windows 98 could only display 16 bits with my graphics card, and better cameras today are capable of 3*10 or 3*12 bit depths, so 24 is neither the beginning, nor the end, it’s just the most widespread currently.)

The optimizations in my software were not finished, but I was too tired and wanted to produce results with what I had, so I ran the renders on a server at my company with CPU time to spare (thank you ArgonSoft). It all took about 50 hours. It would have taken 500 or 5000 hours with a previous version, and maybe it would have taken only 5 hours or 0.5 hours if I had more time, but it doesn’t matter now. The images are ready, so let me present you the results. (Note: sadly the images are temporarily presented here in a scaled down version, because they are huge (50 MB!), and the big interest caused it to bring my site down several times. I promise to reupload them soon.)

Wanna try it out?

You can’t wait to grab the program and try it out, can you? Okay, lucky for you, I’m releasing the source code of the program under the terms of the GPL. The source code can be found here.

I will write a more technical blog post about this topic in a few days.

UPDATE 2014.03.05.: The interest in my video has become huge. Thank you everyone for the nice comments, sharing, etc., I am so happy that my images made you happy . My program was featured on a New Scientist article and Gizmodo and this is the biggest achievement of my career ever. If there is more interest, and you can support and promote this thing, I am planning to continue this project, create screensavers, and writing new algorithms to produce even better images and videos. It won’t be easy next to my day job, but my biggest goal is to bring amazement to you all . Thanks again and enjoy the computer generated art .

UPDATE 2014.04.02.: I’ve been extremely busy lately, I dedicated all my freetime to this project. The Society6 thing didn’t work out the way I hoped, so I removed it from the article, but something better is on the way. The promised follow-up article can be found here.

Post navigation

59 thoughts on “All RGB colors in one image”

Nice work!! It looks really awesome!
Since I like optimizing programs, I couldn’t resist giving it a try, and I’ve succeeded in getting at least the “avg” method down to a reasonably short time (it was easiest to optimize). It can generate a 24-bit (4096*4096) image in maybe 10-20 minutes. Haven’t got time to work on it more today, but I am certainly hooked. It generates such beautiful patterns (I am also the kind of person who really likes fractals).

Aside from other minor optimizations like avoiding LINQ and not spawning a new thread for the png export every time, the main optimization was that the query is basically a nearest neighbour query in RGB space. So I store all the colors in the queue in a 3D array which is divided into buckets. I have found 8*8*8 or 16*16*16 buckets to work best. In each bucket, the colors are relatively similar and are stored in a list. When I search for a color, I start in the bucket which the average of the pixel’s neighbours would fall in, and then I search outwards through the rest of the buckets. The search can be stopped when it detects that no color inside the current bucket can give a difference lower than the currently best candidate pixel. This made the searching more sequential, so I had to scrap multithreading, I later tried to reintroduce it, but that just ended up slowing it down.

I have uploaded my code to github. Please excuse the mess I have made of it. I haven’t had the time to clean it up properly. Also note that invoking it with “avgsq” will actually give you the “avg” algorithm (because I was too lazy to copy and paste lots of code).

That’s not technically possible. All colors means that the number of colors is a power of 2, and also the size is also a power of 2. Such numbers are only divisible by 2. That’s why the sizes are only 128, 256, 512, 1024, 2048, 4096. That means you will have to crop. However I’m thinking about a relaxed algorithm where not all colors are added exactly once, but they look just the same as these ones.

Not necessarily. You could generate an image with 36*36*36 colors if we wanted.
In fact, your program supports this if you just remove the check for if the numbers are powers of two. You just need to make sure that [colors]^3 can be factored into the two numbers you want as width*height, alternatively that Width*Height is a cube. 2880*1800 is not a cube, however 2880*2025 is, so you could use that and crop it slightly.

Of course this wouldn’t be all colors that can be represented by normal 24-bit color values, but that it is exactly 24-bit we use is just a historical coincidence because it happened to be very efficient.

I’m gettin jealous because you got all the fame, just because you were the winner of my challenge, even though my designs can also be stunning. (I can’t quite proclaim myself as the winner, because of my requirements). Also how did you manage to ‘go viral’ before the challenge even ended?

So you’re Zom-B? Please don’t be jealous… I always promoted the Codegolf challenge, the other contributions and allrgb.com. You’re right, there are many other stunning designs there. I’m still trying to put it all together how it happened, I guess it just did. I think people liked the video the most, and the viral thing was a YouTube effect. Look how famous Gangnam style became, I guess the viral factor is mostly random .

Hi Joco,
I really love your Idea, so I shamelessly used it to implement my own version: https://github.com/Dobiasd/All-Colors
If hope you like it and feel honored instead of robbed or something.
Greetings
Dobi

I see you gave me credit and also published your source code under a different, but also free license. I think it should be alright.

I love the style of images that your program produces. Out of curiosity, can you tell me more about how it works, where it’s different from mine? I see that the same colored branches appear in multiple places, and there are those smooth gray border lines which give it a very strange look.

Since I did not really look into your source code, and only read your article, I do not know about all details of your implementation, but here is a rough explanation of mine:

First I also walk the RGB cube with three nested loops, shuffle the colors and sort them by hue. Then I hold a list with posssible next positions which I initalize with some fixed points (2, 3 or 4 at the moment) or a binary input image.

Now I pop the colors from the hue-sorted queue and find the best fitting next possible position.
I find it by adding the euclidian differences of the 8-neighbourhood (only aleady filled pixels) of the possibilities and dividing by the count of filled neighbours. This avoids coral like growing. This unfortunately is the change, that to prohibits me from using a RGB cube nearest neighbour optimization with RTrees or something.

Then I update the possible positions to having every point with a already filled neighbour. Rinse and repeat.
The output images are embellished by filling the remaining black gaps with a half transparent version of a dilated and median-filtered version of itself. This produces the strange border lines. I just found the contrast with black too strong.

Ah, and, as you probably already observed, I use an image size too large to be filled by all pixels, because I like the lettuce like borders and wanted to avoid the last pixels going into holes where they do not really fit.

It’s a basic version of the algorithm, I was mostly curious how efficiently it could be implemented in a language like javascript. The current version takes around 20 seconds to generate a 21bit image and 6.5 minutes to generate a full 24bit image in Chrome. Safari and Firefox are somewhat slower. I did not try IE

I implemented a generator for the min-selection images, random and sorted, using a data structure I came up with based on k-d trees. The blog post is here, and the code is here. Takes around 2 minutes for the random one, and around 4 minutes for the hue-sorted one because the boundary is more complex. I also tried to get rid of some of the artefacts in the hue-sorted image by making multiple passes through the spectrum, to give it a chance to fill in some of the “holes.”

These are really miraculous pictures and your video is mesmerizing.
There’s an article in the german magazin “Focus”, that’s how I got knowledge of your beautiful work. Yes, it’s true…it looks like colourful corals and “rainbow smoke”.