Newer
Older
image_proc / script.js
// Frank's Lab Image Effects
//  https://www.youtube.com/watch?v=UeZ1pTg_nMo
//
// Steve's Makerspace - Art using Satellite Maps
// ref: https://www.youtube.com/watch?v=KytAyWVtr_8

// color palette: https://coolors.co/palettes/popular/5%20colors

// ["264653","2a9d8f","e9c46a","f4a261","e76f51"]
// https://coolors.co/palette/264653-2a9d8f-e9c46a-f4a261-e76f51

//
// Firefox seems to have an issue with rendering.  Google works fine.
//

const canvas = document.getElementById('canvas1');
const ctx = canvas.getContext('2d');
canvas.width = 1024;
canvas.height = 682;

// canvas.width = 1200;
// canvas.height = 675;

class Cell {

    constructor(effect, x, y) {
        this.effect = effect;
        this.x = x;
        this.y = y;
        this.width = this.effect.cellWidth;
        this.height = this.effect.cellHeight;
        this.redAvg = 0;
        this.greenAvg = 0;
        this.blueAvg = 0;
        this.grayValue = undefined;
        this.grayScaleArray = [];
        // this.palette = ["264653","2a9d8f","e9c46a","f4a261","e76f51"];
        // this.palette = ["780116","f7b538","db7c26","d8572a","c32f27"];
        // this.palette = ["220901","621708","941b0c","bc3908","f6aa1c"];  // prettiest
        this.palette = ["172121","444554","7f7b82","bfacb5","e5d0cc"]; // gray scale
        this.slideX = 0;
        this.slideY = 0;
        this.image = document.getElementById('projectImage');
    }

    draw(context) {
        // if (this.grayValue === undefined) {
            context.drawImage(this.image, this.x, this.y, this.width, this.height
                , this.x, this.y, this.width, this.height);
            // context.strokeRect(this.x, this.y, this.width, this.height);
            // if (this.x === 0 && this.y === 0) {
                
                for(let y = this.y; y < this.y + this.height; y++) {
                    for(let x = this.x; x < this.x + this.width; x++) {
                        const data = context.getImageData(x, y,1, 1);
                        this.redAvg += data.data[0];
                        this.greenAvg += data.data[1];
                        this.blueAvg += data.data[2];
                    }
                }
                const totalPixels = this.width * this.height ;
                this.redAvg = Math.floor(this.redAvg / totalPixels);
                this.greenAvg = Math.floor(this.greenAvg / totalPixels);
                this.blueAvg = Math.floor(this.blueAvg / totalPixels);
                this.grayValue = this.calculateGrayAmount(this.redAvg, this.greenAvg, this.blueAvg);
                // console.log('Gray value: ' + this.grayValue);
                
            // } 
            const paletteIndex = Math.floor(this.grayValue / 50);
            // const paletteIndex = this.grayValue % this.palette.length;
            console.log('(' + this.x + ', ' + this.y + ') palIndex:' + paletteIndex);
            context.fillStyle = '#' + this.palette[paletteIndex];
            // context.fillStyle = "rgb(" + this.redAvg + "," + this.greenAvg + "," + this.blueAvg + ")";
            context.fillRect(this.x, this.y, this.width, this.height);
        // } 
        
        // if (this.grayValue !== undefined) {
        //     // console.log('Here...');
        //     const paletteIndex = Math.floor(this.grayValue / 50);
        //     // const paletteIndex = this.grayValue % 3;
        //     console.log('(' + this.x + ', ' + this.y + ') palIndex:' + paletteIndex);
        //     context.fillStyle = '#' + this.palette[paletteIndex];
        //     // context.fillStyle = "rgb(" + this.redAvg + "," + this.greenAvg + "," + this.blueAvg + ")";
        //     context.fillRect(this.x, this.y, this.width, this.height);
        // }
    }

    calculateGrayAmount(red, green, blue) {
        // determine the grayAmount from the color at the pixel
        // ref: https://www2.cs.uic.edu/~i101/labs/lab8.html
        return Math.floor(red * 0.299 + green * 0.587 + blue * 0.114);
    }
}

class Effect {
    constructor(canvas) {
        this.canvas = canvas;
        this.width = this.canvas.width;
        this.height = this.canvas.height;
        this.numCols = this.canvas.width;
        this.numRows = this.canvas.height;
        // this.numCols = 64;
        // this.numRows = 31;
        this.cellWidth = this.width / this.numCols;
        this.cellHeight = this.height / this.numRows;
        this.imageGrid = [];
        this.createGrid();
        // this.cell = new Cell(this, 0, 0);
        
        // console.log(this.imageGrid);
    }

    createGrid() {
        for(let y = 0; y < this.height; y += this.cellHeight) {
            for(let x = 0 ; x < this.width; x += this.cellWidth) {
                this.imageGrid.push(new Cell(this, x, y));
            }
        }
    }

    render(context) {
        // this.cell.draw(context);
        this.imageGrid.forEach(cell=> {
            // cell.update();
            cell.draw(context);
        })
    }

}

const effect = new Effect(canvas);
// console.log(effect);
// effect.render(ctx);

function animate() {
    effect.render(ctx);
    // requestAnimationFrame(animate);
}

animate();

/*
TODO:
1. For each cell:
    a. average red, green and blue colors
    b. calculate gray amount
    c. determine palette color
        i.  0 - 50, 51 - 101, 102 - 152, 153 - 203, 204 - 255
*/