How can I make a mosaic from a given number of 1x1 bricks and a picture?
In case anyone familiar with JavaScript is interested, I wrote this script (tested in Firefox 19) which lets the user specify the number of tiles (bricks) of each colour and browse for an image file with the same number of pixels.

The luma (brightness) of each pixel is ranked and assigned one of the listed colours. Any ties are arbitrarily assigned to either possible colour (as JavaScript's sort is unstable).

http://upload.wikimedia.org/wikipedia/commons/thumb/5/55/Mona_Lisa_headcrop.jpg/20px-Mona_Lisa_headcrop.jpg  is an image which fits the example tile count.

&lt;html&gt;
 &lt;head&gt;&lt;title&gt;Make mosaic given tile colour count&lt;/title&gt;&lt;/head&gt;
 &lt;body&gt;&lt;form onSubmit="return false;"&gt;
  &lt;textarea id="counts" rows="3" cols="80"&gt;// Ordered from darkest to lightest
colours = [ '#000000', '#993300', '#cc0000', '#ff9900', '#ffff00', '#ffffff' ];
tiles   = [       110,        40,        80,        60,       120,        90 ];
tileWidth = tileHeight = 16;&lt;/textarea&gt;&lt;br /&gt;
  &lt;input type="file" id="file" size="80" /&gt;
  &lt;img id="img" align="top" /&gt;&lt;br /&gt;
  &lt;input type="button" value="Go!" onClick="loadImage()" /&gt;&lt;br /&gt;&lt;br /&gt;
  &lt;canvas id="canvas" style="background:#808080;border:2px groove;"&gt;&lt;/canvas&gt;
  &lt;script&gt;
var tileWidth = 16, tileHeight = 16, colours, tiles;
// Based on http://jsfiddle.net/fWLJ9/
var canvas  = document.getElementById('canvas');
var context = canvas.getContext('2d');
var img     = document.getElementById('img');
var imgData;
function loadImage() {
 var url = window.URL || window.webkitURL;
 var src = url.createObjectURL(document.getElementById('file').files[0]);
 img.src = src;
 img.onload = function() {
  resizeCanvas();
  context.drawImage(img, 0, 0);
  url.revokeObjectURL(src);
  imgData = context.getImageData(0, 0, img.width, img.height).data;
  makeMosaic();
 }
}
function resizeCanvas() {
 canvas.width  = img.width  * tileWidth  - 1;
 canvas.height = img.height * tileHeight - 1;
}
function makeMosaic() {
 // Check counts are correct
 eval(document.getElementById('counts').value);
 var count = 0;
 for (var i = 0; i &lt; colours.length; ++i) { count += tiles[i]; }
 if (count != img.width * img.height) {
  alert(img.width * img.height + ' pixels but ' + count + ' tiles!');
  return;
 }
 // Read pixels' luma
 var lumas = new Array();
 for (var y = 0; y &lt; img.height; ++y) {
  for (var x = 0; x &lt; img.width; ++x) {
   lumas.push({ x:x, y:y, luma:getPixelLuma(x, y) });
  }
 }
 // Sort in ascending order
 lumas.sort(function(a, b) { return a.luma - b.luma });
 // Assign pixels to colours
 resizeCanvas();
 count = 0;
 for (var i = 0; i &lt; colours.length; ++i) {
  context.fillStyle = colours[i];
  for (var j = 0; j &lt; tiles[i]; ++j) {
   context.fillRect(lumas[count].x * tileWidth, lumas[count].y * tileHeight,
                    tileWidth - 1, tileHeight - 1);
   ++count;
  }
 }
}
function getPixelLuma(x, y) {
 var pixelOffset = (x + y * img.width) * 4;
 return (0.21 * imgData[pixelOffset] + 0.72 * imgData[pixelOffset + 1] +
         0.07 * imgData[pixelOffset + 2]).toFixed(2);
}
  &lt;/script&gt;
 &lt;/form&gt;&lt;/body&gt;
&lt;/html&gt;