In this article, I will introduce how to automatically create mosaic art using images of 18 Pokemon from the input image.
There may be a smarter way, but ...
PhotoMosaic.java
GetAverage.java
3.2 Color reduction based on the color average of 2 ReduceColor.java
Place the Pokemon of the color selected in 4.3 `PhotoMosaic.java`
I will implement it like that.
--The image import / export part is omitted.
PhotoMosaic.java
import java.awt.image.*;
import java.awt.Graphics;
public class PhotoMosaic {
static BufferedImage execute(BufferedImage before_image) {
int width = before_image.getWidth();
int height = before_image.getHeight();
BufferedImage after_image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
Graphics g = after_image.getGraphics();
BufferedImage image[] = new BufferedImage[18];
image[0] = JpegFileReader.read("image/white.png ");
image[1] = JpegFileReader.read("image/fuchsia.png ");
image[2] = JpegFileReader.read("image/lime.png ");
image[3] = JpegFileReader.read("image/blue.png ");
image[4] = JpegFileReader.read("image/black.png ");
image[5] = JpegFileReader.read("image/maroon.png ");
image[6] = JpegFileReader.read("image/olive.png ");
image[7] = JpegFileReader.read("image/silver.png ");
image[8] = JpegFileReader.read("image/red.png ");
image[9] = JpegFileReader.read("image/green.png ");
image[10] = JpegFileReader.read("image/navy.png ");
image[11] = JpegFileReader.read("image/yellow.png ");
image[12] = JpegFileReader.read("image/aqua.png ");
image[13] = JpegFileReader.read("image/gray.png ");
image[14] = JpegFileReader.read("image/purple.png ");
image[15] = JpegFileReader.read("image/teal.png ");
image[16] = JpegFileReader.read("image/beige.png ");
image[17] = JpegFileReader.read("image/orange.png ");
//Declare an array to hold the cropped image
BufferedImage[][] split_image = new BufferedImage[width/40][height/40];
for ( int i=0; i*40<width; i++ ) {
for ( int j=0; j*40<height; j++ ) {
//40 original images*Cut to 40
split_image[i][j] = before_image.getSubimage( i*40, j*40, 40, 40 );
//Take the color average of the cropped image
int color_num = ReduceColor.detectColor(GetAverage.execute(split_image[i][j]));
g.drawImage(image[color_num], i*40, j*40, null);
}
}
g.dispose();
return after_image;
}
}
GetAverage.java
import java.awt.image.*;
import java.awt.Color;
public class GetAverage{
static int[] execute(BufferedImage image){
int R = 0, G = 0, B = 0;
// Average[0]->Red, Average[1]->Green, Average[2]->Blue
int Average[] = new int[3];
//Take the RGB values of the pixels to get the total
for (int i=0; i<40; i++ ) {
for (int j=0; j<40; j++ ) {
int tmp_color = image.getRGB(i,j);
Color color = new Color(tmp_color);
R += color.getRed();
G += color.getGreen();
B += color.getBlue();
}
}
//Find the average value of pixels
Average[0] = (int)R/1600;
Average[1] = (int)G/1600;
Average[2] = (int)B/1600;
return Average;
}
}
ReduceColor.java
public class ReduceColor{
static int detectColor(int[] Average){
int R = getNearestValue(Average[0]);
int G = getNearestValue(Average[1]);
int B = getNearestValue(Average[2]);
//An array to put the subscripts of the array of images to be converted
int[][][] v = new int[256][256][256];
v[64][64][64] = 4; // black
v[64][64][128] = 10; // navy
v[64][64][192] = 3; // blue
v[64][64][255] = 3; // blue
v[64][128][64] = 9; // green
v[64][128][128] = 15; // teal
v[64][128][192] = 15; // teal
v[64][128][255] = 3; // blue
v[64][192][64] = 2; // lime
v[64][192][128] = 15; // teal
v[64][192][192] = 12; // aqua
v[64][192][255] = 3; // blue
v[64][255][64] = 2; // lime
v[64][255][128] = 2; // lime
v[64][255][192] = 12; // aqua
v[64][255][255] = 12; // aqua
v[128][64][64] = 5; // maroon
v[128][64][128] = 14; // purple
v[128][64][192] = 14; // purple
v[128][64][255] = 3; // blue
v[128][128][64] = 6; // olive
v[128][128][128] = 13;// gray
v[128][128][192] = 3; // blue
v[128][128][255] = 3; // blue
v[128][192][64] = 9; // green
v[128][192][128] = 2; // lime
v[128][192][192] = 12;// aqua
v[128][192][255] = 12;// aqua
v[128][255][64] = 2; // lime
v[128][255][128] = 2; // lime
v[128][255][192] = 2; // lime
v[128][255][255] = 12;// aqua
v[192][64][64] = 8; // red
v[192][64][128] = 1; // fuchsia
v[192][64][192] = 1; // fuchsia
v[192][64][255] = 14; // purple
v[192][128][64] = 17; // orange
v[192][128][128] = 16;// beige
v[192][128][192] = 1; // fuchsia
v[192][128][255] = 1; // fuchsia
v[192][192][64] = 11; // yellow
v[192][192][128] = 11; // yellow
v[192][192][192] = 0; // white
v[192][192][255] = 12;// aqua
v[192][255][64] = 12; // aqua
v[192][255][128] = 2; // lime
v[192][255][192] = 0; // white
v[192][255][255] = 12;// aqua
v[255][64][64] = 8; // red
v[255][64][128] = 8; // red
v[255][64][192] = 1; // fuchsia
v[255][64][255] = 1; // fuchsia
v[255][128][64] = 17; // orange
v[255][128][128] = 16;// beige
v[255][128][192] = 1; // fuchsia
v[255][128][255] = 1; // fuchsia
v[255][192][64] = 11; // yellow
v[255][192][128] = 11;// yellow
v[255][192][192] = 16;// beige
v[255][192][255] = 16;// beige
v[255][255][64] = 11; // yellow
v[255][255][128] = 11;// yellow
v[255][255][192] = 0; // white
v[255][255][255] = 0; // white
return v[R][G][B];
}
public static int getNearestValue(int v){
int num=0; //Array subscript
int difference; //Array value-Absolute value of RGB value v
int[] list = {64,128,192,192};
// System.out.println("The value of v is"+v);
difference = Math.abs( list[0] - v );
for ( int i = 1; i < list.length; i++ ) {
if ( Math.abs( list[i] - v ) < difference ) {
num = i;
difference = Math.abs( list[i] - v );
}
}
return list[num];
}
}
(Click to enlarge)
――It was quite difficult to reduce the color. Especially when it was light blue, it was judged to be white and it didn't work. ――The red color was relatively nice. ――Since there are only 18 colors, landscape photography is difficult.
--Cut a part of the image using BufferedImage_getSubimage.
Recommended Posts