Utilizing HTML5 Canvas to apply color theme to .png icons
Pretty nice overall. You're missing a semi-colon or two, but otherwise it's a nice solution.

The only real criticism I have are the "magic numbers" in there, like the 40x40 size that's hardcoded everywhere. Technically, you could derive the canvas dimension from the image, or pass the width/height as arguments. (Incidentally, setting a canvas's size will also clear its contents, which is helpful if there's one shared canvas that needs to be cleared between uses.) In either case, though, you'd have to get rid of the hardcoded "40".

Optimization-wise, the only addition I've made is to simply skip pixels with a zero alpha component; if they're transparent anyway, there's no need to bother with them.

Other than that, I've just broken the code into a couple of functions; nothing special (Note, haven't tested this yet.)

var changeIconColor = (function () {
  var canvas  = document.createElement("canvas"), // shared instance
      context = canvas.getContext("2d");

  // only place the dimensions are hardcoded
  // everything else just references canvas.width/canvas.height
  canvas.width  = 40;
  canvas.height = 40;

  function desaturate() {
    var imageData = context.getImageData(0, 0, canvas.width, canvas.height),
        pixels    = imageData.data,
        i, l, r, g, b, a, average;

    for(i = 0, l = pixels.length ; i &lt; l ; i += 4) {
      a = pixels[i + 3];
      if( a === 0 ) { continue; } // skip if pixel is transparent

      r = pixels[i];
      g = pixels[i + 1];
      b = pixels[i + 2];

      average = (r + g + b) / 3 &gt;&gt;&gt; 0; // quick floor
      pixels[i] = pixels[i + 1] = pixels[i + 2] = average;
    }

    context.putImageData(imageData, 0, 0);
  }

  function colorize(color) {
    context.globalCompositeOperation = "source-atop";
    context.globalAlpha = 0.3; // you may want to make this an argument
    context.fillStyle   = color;
    context.fillRect(0, 0, canvas.width, canvas.height);
    // reset
    context.globalCompositeOperation = "source-over";
    context.globalAlpha = 1.0;
  }

  return function (iconElement, color) {
    context.clearRect(0, 0, canvas.width, canvas.height);
    context.drawImage(iconElement, 0, 0, canvas.width, canvas.height);
    desaturate();
    colorize(color);
    return canvas.toDataURL("image/png", 1);
  };
}());


As for invoking it, I don't think you need the $.proxy and promise stuff. I would think it'd be enough to just do

$('.custom-module').each(function () {
    this.src = changeIconColor(this, '#33CC33');
});
$('.module-li').removeClass('hidden');