JSFiddle - React, Tailwind, and code Playground

HTML

<canvas id="canvas1" width="150" height="150" style="border: 1px solid black"></canvas>
<p>
<button type="button" onclick="grayscale();">Tint me!</button>
</p>

<script>
    function grayscale() {
    // you have to put the onclick part here because jsfiddle is silly
    var can = document.getElementById('canvas1');
    var ctx = can.getContext('2d');
    
    var imageData = ctx.getImageData(0,0,can.width, can.height);
    var pixels = imageData.data;
    var numPixels = pixels.length;
    
    ctx.clearRect(0, 0, can.width, can.height);
    
    for (var i = 0; i < numPixels; i++) {
        var average = (pixels[i*4] + pixels[i*4+1] + pixels[i*4+2]) /3;
        // set red green and blue pixels to the average value
        pixels[i*4] = average;
        pixels[i*4+1] = average+30;
        pixels[i*4+2] = average;
    }
    ctx.putImageData(imageData, 0, 0);
}
</script>

JavaScript

var can = document.getElementById('canvas1');
var ctx = can.getContext('2d');

function roughSizeOfObject( object ) {

    var objectList = [];
    var stack = [ object ];
    var bytes = 0;

    while ( stack.length ) {
        var value = stack.pop();

        if ( typeof value === 'boolean' ) {
            bytes += 4;
        }
        else if ( typeof value === 'string' ) {
            bytes += value.length * 2;
        }
        else if ( typeof value === 'number' ) {
            bytes += 8;
        }
        else if
        (
            typeof value === 'object'
            && objectList.indexOf( value ) === -1
        )
        {
            objectList.push( value );

            for( i in value ) {
                stack.push( value[ i ] );
            }
        }
    }
    return bytes;
}

var img = new Image();
img.src =...