Dart People Mosaic
Photo mosaics have fascinated me for quite a while, so some time ago I had the idea of turning a profile photo into a photo mosaic using the profile photos of people in your circles. I then quickly forgot about that idea, remembered it again, started with some coding, got distracted with some other projects, remembered it once again, found my code and finished the project now.
Originally I had planned to implement it using Dart Isolates/Webworkers but I have run into some problems with this approach. Firstly Isolates don't have access to the DOM, meaning I couldn't use Canvas objects there (and Dart isolates can't use HttpRequest either which I could have used for fetching the list of people from the Google+ API). So I did all the fetching and getting the colour information for all the profile images asynchronously in the main process.
So I'm now doing all the calculations in the main process, but asynchronously via Futures as to not freeze the browser completely.
Another challenge I came across is how best to calculate an average colour for an image to match against a pixel of the main image. My first attempt was using drawImageScaled(img, 0, 0, 1, 1) on a 1x1 pixel canvas, but the canvas image scaling method didn't work nicely.
As it turns out I could let Google do this work for me by appending a `sz=1` parameter to the profile images, which gave a much better average colour for the image and didn't take any computation on my side at all.
So the full process works like this now:
1 -> Sign in with Google
2 -> Fetch profile image and list of people via Google+ API
3 -> Fetch profile images for all people in two sizes: one small image to be used in the mosaic and one 1x1 pixel image to get the colour.
4 -> Put the profile image on a canvas and read out the pixel colours.
5 -> For each pixel find a close match from the profile images (trying to reduce reuse of images as much as possible)
6 -> Put the small profile images in the correct spot of the mosaic.
There's a version of this live here if you want to give it a try:https://scary-experiments.appspot.com/dartmosaic/
It takes a while at first to load all people and profile images, but you can then play around with the tolerance parameter to see what produces the best results for your profile photo selection.
Smaller values will match the colours more closely, but you will have a higher rate of repeated profile photos.
Higher values will add more diversity but can easily distort the image.
I found the best results between 5-10 for me, but that totally depends on what and how many photos are available.
If you don't like the photo selection you can always "Disconnect" and then Sign in again and choose different circles to expose to the script during authentication.
There are definitely much better photo mosaic algorithms out there, but this one works rather quickly AND is fully implemented in Dart, which I think is a first ;)
Source code available if you want to play with it a bit, e.g. using other images than your profile image like I did with the Dart logo in the screenshot :)https://github.com/Scarygami/dart_people_mosaic #gde #googleplus #dart #dartlang #opensourcecode