by

FixOutlook mosaic avatar finder (part 2)

Yesterday I wrote about the avatar finder I was building. I posted a comment to the blog of the Email Standards Project asking for avatars. digirati replied and send me their avatar, but unfortunately they weren’t able to locate themselves in the mosaic. So now I had the source image of an avatar which was quite likely to be included (as digirati was one of the first 1,000 people to tweet their support) but still no (edited?) tile. Luckily, digirati’s avatar had quite a lot of pixels of the same color (R = 34, G = 34, B = 34), so I decided to pixel scan all tiles I had separated from the mosaic earlier and save them to a database.

Here’s digirati’s avatar:

digirati's twitter avatar

And here’s the code:

$start = $argv[1];
$loop = 15;
for ($i = $start; $i < ($start+$loop); $i++) {
    // Create resource from image
    $image = @imagecreatefrompng('tiles/tile_' . $i . '.png');

    $width = imagesx($image);
    $height = imagesy($image);

    // Loop through all pixels
    for ($y = 0; $y < $height; $y++) {
        for ($x = 0; $x < $width; $x++) {             // Extract RGBA values from pixel             $rgba = imagecolorat($image, $x, $y);             $r = ($rgba >> 16) & 0xFF;
            $g = ($rgba >> 8) & 0xFF;
            $b = $rgba & 0xFF;
            $alpha = ($rgba & 0x7F000000) >> 24;

            // Save pixel RGBA values to database
            $query = sprintf("INSERT INTO gd_pixels (tile, x, y, r, g, b, alpha) VALUES (%d, %d, %d, %d, %d, %d, %d)", mysql_real_escape_string($i), mysql_real_escape_string($x), mysql_real_escape_string($y), mysql_real_escape_string($r), mysql_real_escape_string($g), mysql_real_escape_string($b), mysql_real_escape_string($alpha));
            $db-> query($query);
        }
    }
}

Because I already had separate tiles I didn’t have to scan the whole image at once but could just scan tile for tile. I created a little bash script which called the PHP script with a $start argument. This argument contained the first tile to process, after which the PHP script processed 15 tiles before finishing execution after which the next 15 tiles would be processed. My MacBook pixel scanned about 4 tiles per second, so after about 75 minutes all tiles were scanned. Now that I have a gd_pixel table weighing just over 30 million rows it’s time to search for digirati’s avatar.

The following query yielded quite some results:

SELECT tile,COUNT(*) AS pixel_count FROM gd_pixels WHERE (r = 34 AND g = 34 AND b = 34) GROUP BY tile ORDER BY pixel_count DESC;

Avatars with RGB values set to 34

But unfortunately, not the right one. So I tried to broaden the search area by looking for RGB values between 30 and 38. The pixel colors could have changed due to JPG compression or editing by the mosaic creators of course.

SELECT tile,COUNT(*) AS pixel_count FROM gd_pixels WHERE ((r > 30 AND r < 38) AND (g > 30 AND g < 38) AND (b > 30 AND b < 38)) GROUP BY tile ORDER BY pixel_count DESC;

Tiles with RGB values varying between 30 and 38

Still no dice :( Broadening the search even more than this would yield to much irrelevant results. So now there are three options:

  1. I’m doing something wrong;
  2. through editing the pixel colors changed so much that it would be very hard to look up any specific avatar at all;
  3. or digirati is not in the mosaic at all.

Unfortunately, now I’m back at square 1. So if you happen to found yourself in the mosaic, please let me know :)

Write a Comment

Comment