let img; let morphs = []; // The order of the morphs, being mapped to the grayscale const orderedMorphs = [5,6,0,4,1,2,3]; let count = 7; let size = 10; let countH = 800; let countV = 520; // Load the image and symbols function preload() { img = loadImage('/assets/mona-lisa.jpg'); for (let i = 0; i < count; i++) morphs[i] = loadSVG(`/assets/morphs/${i}.svg`); } function setup() { pixelDensity(1); // Display the image img.resize(0, countH); img.filter(GRAY); createCanvas(countV, countH); image(img, 0, 0); describe('Mona lisa - by Davincci'); // Load the pixels of the canvas // This is a 1D array of integers with the rgba values of the pixels loadPixels(); let i = 0; let j = 0; // Create an array containing only the grayscale of every pixel let pixels1d = []; // Since the picture is gray, the first 3 values (rgb) for every picture are similar // We need the value at indexes 0,4,7,... for (let i = 0; i < pixels.length; i += 4) pixels1d.push(pixels[i]); // Combine every 10 values into one by calculating their average // Put the result in a 2D array, the rows are the pixel-rows of the image // The columns are grayscale averages of every 10 pixel-columns of the picture let averages = new Array(countH); for (let i = 0; i < averages.length; i++) averages[i] = new Array(countV/10); let sum = 0; for(let k = 0; k < pixels1d.length; k++) { sum += pixels1d[k]; if (j%10 == 0) { averages[i][Math.floor(j/10)] = sum/10; sum = 0; } j++; if (k%countV == 0 && k>0) { i++; j = 0; } } // Combine every 10 rows into one row by calculating the average of the values of every column // Put the result into a new array 'average2' let sums = new Array(countV/10).fill(0); let averages2 = new Array(countH/10); for (let i = 0; i < averages2.length; i++) averages2[i] = new Array(countV/10); for (let i = 0; i < averages.length; i++) { for (let j = 0; j < averages2[0].length; j++) { sums[j] += averages[i][j]; if (i%10 == 0) { averages2[i/10][j] = Math.round(sums[j]/10); sums[j] = 0; } } } // Find the min and max value in averages2 let minGray = Infinity; let maxGray = -Infinity; for (let i = 0; i < averages2.length; i++) { for (let j = 0; j < averages2[i].length; j++) { let val = averages2[i][j]; if (val < minGray) minGray = val; if (val > maxGray) maxGray = val; } } // Scale all values of averages2 between minGray and maxGray for (let i = 0; i < averages2.length; i++) { for (let j = 0; j < averages2[i].length; j++) { // Scale between 0.0 - 1.0 let normalized = (averages2[i][j] - minGray) / (maxGray - minGray); // Map to 0 - 6 (the morph indexes) averages2[i][j] = Math.round(normalized * 6)%7; } } let svgCanvas = createGraphics(countV*2,countH,SVG); svgCanvas.image(img, 0, 0); for (let i = 0; i < countH/10; i++) { for (let j = 0; j < countV/10; j++) { svgCanvas.image(morphs[orderedMorphs[averages2[i][j]]], j*size+countV+size, i*size, size, size); } } svgCanvas.save("morphed-mona-lisa.svg"); }