Converting images loaded by imageryprovider into grayscale color

I am trying to convert images loaded by imageryprovider into grayscale color using the below pseudo codes. I would like to seek your advice if this is the right way or there are other better approach in terms of performance?

Also, if I need to toggle between viewing of map tiles in grayscale and original color, does that means I have to reconstruct the imageryprovider again?

Cesium.TileMapServiceImageryProvider.prototype.requestImage = function(x, y, level) {
  var tt = Cesium.ImageryProvider.loadImage(this, url);
  if (tt && grayscale) { // grayscale is a boolean flag
    tt.then(function(image) {

      var canvas = document.createElement('canvas');
      canvas.width = 256;
      canvas.height = 256;
      var context = canvas.getContext('2d');
      context.drawImage(image, 0, 0);
      var imageData = context.getImageData(0, 0, 256, 256);
      var data =;
      var v;
      for (var i=0, n=data.length; i<n; i+=4) {
        v = (data[i]+data[i+1]+data[i+2])/3;
        data[i] = data[i+1] = data[i+2] = v;
      context.putImageData(imageData, 0 ,0);
      image.src = canvas.toDataURL();
    }).otherwise(function(error) {
  return tt;

Unless you have very specific requirements for grayscale, you can just set layer.saturation to 0. Here’s a working example:

This will be infinitely faster than your above approach because it is hardware accelerated.

That works. Thanks Mathew.