Tried the below code but the browser crashes when the raster tile dimensions are large due to the number of iterations in the nested for loop. Mapbox recently released a feature to colorise raster tile layer but maplibre hasn't released yet.
The below code tries to read pixels from mapbox canvas and paints another overlayed canvas pixel by pixel based on the grayscale avg value, i assign a color to the overlayed canvas
const coloriseRasterTile = () => {
if (!map.getLayer(`id-${id}`) && !map.getSource(`id-${id}`)) return;
var customCanvas = document.getElementById('canvasID');
var rasterTileBounds = [-76.76666666666668, 39.26666488571745, -76.73334678524573, 39.36666666666667];
var canvasWidth = Math.abs(
parseFloat(
map.project([rasterTileBounds[0], rasterTileBounds[1]]).x -
map.project([rasterTileBounds[2], rasterTileBounds[1]]).x,
10,
),
);
var canvasHeight = Math.abs(
parseFloat(
map.project([rasterTileBounds[0], rasterTileBounds[1]]).y -
map.project([rasterTileBounds[0], rasterTileBounds[3]]).y,
10,
),
);
customCanvas.width = canvasWidth;
customCanvas.height = canvasHeight;
var overlayCtx = customCanvas.getContext('2d');
if (overlayCtx) {
customCanvas.style.display = 'none';
}
const canvas = map.getCanvas();
const gl = canvas.getContext('webgl') || canvas.getContext('webgl2');
const data = new Uint8Array(4);
if (!gl) return;
for (let x = 0; x < canvasWidth; x++) {
for (let y = 0; y < canvasHeight; y++) {
const canvasX = x - canvas.offsetLeft;
const canvasY = canvas.height - y - canvas.offsetTop;
const bufferX = ((gl.drawingBufferWidth / canvasWidth) * x).toFixed(0);
const bufferY = ((gl.drawingBufferHeight / canvasHeight) * (canvasHeight - y)).toFixed(0);
gl.readPixels(bufferX, bufferY, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, data);
const [r, g, b, a] = data;
const avg = r + g + b / 3;
overlayCtx.fillStyle = avg < 125 ? 'green' : 'blue';
overlayCtx.fillRect(x, y, 1, 1);
}
}
map.addSource('canvas-source', {
type: 'canvas',
canvas: 'canvasID',
coordinates: [
[rasterTileBounds[0], rasterTileBounds[1]],
[rasterTileBounds[2], rasterTileBounds[1]],
[rasterTileBounds[2], rasterTileBounds[3]],
[rasterTileBounds[0], rasterTileBounds[3]],
],
});
map.addLayer({
id: 'canvas-layer',
type: 'raster',
source: 'canvas-source',
});
};