Problem Statement and Background Image and Video filters Ascii art Photo Mosaic
Is a picture (usually a photograph) that has been divided into (usually equal sized) tiled sections, each of which is replaced with another photograph that matches the target photo, basically swapping one pixel for an image.
the resolution of the image will determine how many images we'll have to use (one per pixel) for example:
if we have an image that is 512x512 we'll have to use 262144 images, but in this case the images will be very small and could not be appreciated without a good resolution so...
First we have to resize the image that we want to convert into, in order to appreciate the little images that we want to put in
then with an image collection we take the average brightness of each one and clasiffy them into 256 brightness values, we replace each pixel of our image with an image that be equals with the brightness of this pixel and repeat at each pixel
finally the full image in mosaic
The markdown of the above sketch looks like:
1link> :P5 sketch=/docs/sketches/mosaic.js, width=512, height=512
And the p5 sketch that loads the original image is the following:
1linklet sclDiv = 100;
2linklet w, h;
3linklet imgAmount = 300;
4link
5linklet brightnessValues = [];
6linklet allImages = [];
7linklet brightImages = [];
8linklet img;
9linklet smaller;
10link
11linkfunction transform(index) {
12link let val = "";
13link index = str(index);
14link for (let i = 0; i < 4-index.length;i++) {
15link val += "0";
16link }
17link val += index;
18link return val;
19link}
20link
21linkfunction preload() {
22link img = loadImage('/vc/docs/sketches/lenna.png');
23link for (i = 0; i < imgAmount; i++) {
24link now = "/vc/docs/sketches/apmw_birds/apmw_base_birds_" + transform(i+1) + '.jpg';
25link allImages[i] = loadImage(now);
26link }
27link}
28link
29linkfunction setup() {
30link createCanvas(img.width, img.width);
31link scl = width / sclDiv;
32link for (let i = 0; i < 256; i++) {
33link brightImages.push(i);
34link }
35link for (let i = 0; i < allImages.length; i++) {
36link let image = allImages[i];
37link
38link allImages[i] = createImage(scl, scl);
39link allImages[i].copy(image, 0, 0, image.width, image.height, 0, 0, scl, scl);
40link image.loadPixels();
41link
42link let avg = 0;
43link for (let j = 0; j < image.height; j++) {
44link for (let k = 0; k < image.width; k++) {
45link let index = (k + j*image.width);
46link let r = image.pixels[index*4];
47link let g = image.pixels[index*4+1];
48link let b = image.pixels[index*4+2];
49link let gray = r *0.2126 + g *0.7152 + b *0.0722;
50link avg += gray;
51link }
52link }
53link
54link avg /= image.height*image.width;
55link brightnessValues[i] = avg;
56link }
57link
58link for ( i = 0; i < brightImages.length; i++) {
59link let record = 256;
60link for ( j = 0; j < brightnessValues.length; j++) {
61link let diff = abs(i - brightnessValues[j]);
62link if (diff < record) {
63link record = diff;
64link brightImages[i] = allImages[j];
65link }
66link }
67link }
68link
69link
70link w = img.width / scl;
71link h = img.height / scl;
72link smaller = createImage(w, h);
73link smaller.copy(img, 0, 0, img.width, img.height, 0, 0, w, h);
74link
75link
76link}
77link
78link
79link
80linkfunction draw() {
81link background(0);
82link smaller.loadPixels();
83link for (let x = 0; x < w; x++) {
84link for (let y = 0; y < h; y++) {
85link let index = x + y * w;
86link let r = smaller.pixels[index*4];
87link let g = smaller.pixels[index*4+1];
88link let b = smaller.pixels[index*4+2];
89link let gray = r *0.2126 + g *0.7152 + b *0.0722;
90link let imageIndex = floor(gray);
91link image(brightImages[imageIndex], x * scl, y * scl, scl, scl);
92link }
93link }
94link noLoop();
95link}
96link
Problem Statement and Background Image and Video filters Ascii art Photo Mosaic