Java - özyinelemeli yolu
2x3 kapalı bir yoldan başlıyorum. Yolun her hücresini tarıyorum ve onu yeni bir 3x3 alt yola bölüyorum. Her seferinde orijinal resme "benzeyen" 3x3 alt yolunu seçmeyi deniyorum. Yukarıdaki işlemi 4 kez tekrar ediyorum.
İşte kod:
package divide;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.imageio.ImageIO;
import snake.Image;
public class Divide {
private final static int MULT = 3;
private final static int ITERATIONS = 4;
public static void main(String[] args) throws IOException {
BufferedImage src = ImageIO.read(Image.class.getClassLoader().getResourceAsStream("input.png"));
BufferedImage dest = new BufferedImage(src.getWidth() * MULT, src.getHeight() * MULT, BufferedImage.TYPE_INT_RGB);
for (int y = 0; y < src.getHeight() * MULT; y++) {
for (int x = 0; x < src.getWidth() * MULT; x++) {
dest.getRaster().setPixel(x, y, new int [] {255, 255, 255});
}
}
List<String> tab = new ArrayList<String>();
tab.add("rg");
tab.add("||");
tab.add("LJ");
for (int k = 1; k <= ITERATIONS; k++) {
boolean choose = k>=ITERATIONS-1;
// multiply size by 3
tab = iterate(src, tab, choose);
// fill in the white space - if needed
expand(src, tab, " r", " L", "r-", "L-", choose);
expand(src, tab, "g ", "J ", "-g", "-J", choose);
expand(src, tab, "LJ", " ", "||", "LJ", choose);
expand(src, tab, " ", "rg", "rg", "||", choose);
expand(src, tab, "L-J", " ", "| |", "L-J", choose);
expand(src, tab, " ", "r-g", "r-g", "| |", choose);
expand(src, tab, "| |", "| |", "Lg|", "rJ|", choose);
expand(src, tab, "--", " ", "gr", "LJ", choose);
expand(src, tab, " ", "--", "rg", "JL", choose);
expand(src, tab, "| ", "| ", "Lg", "rJ", choose);
expand(src, tab, " |", " |", "rJ", "Lg", choose);
for (String s : tab) {
System.out.println(s);
}
System.out.println();
}
for (int j = 0; j < tab.size(); j++) {
String line = tab.get(j);
for (int i = 0; i < line.length(); i++) {
char c = line.charAt(i);
int xleft = i * dest.getWidth() / line.length();
int xright = (i+1) * dest.getWidth() / line.length();
int ytop = j * dest.getHeight() / tab.size();
int ybottom = (j+1) * dest.getHeight() / tab.size();
int x = (xleft + xright) / 2;
int y = (ytop + ybottom) / 2;
if (c == '|') {
drawLine(dest, x, ytop, x, ybottom);
}
if (c == '-') {
drawLine(dest, xleft, y, xright, y);
}
if (c == 'L') {
drawLine(dest, x, y, xright, y);
drawLine(dest, x, y, x, ytop);
}
if (c == 'J') {
drawLine(dest, x, y, xleft, y);
drawLine(dest, x, y, x, ytop);
}
if (c == 'r') {
drawLine(dest, x, y, xright, y);
drawLine(dest, x, y, x, ybottom);
}
if (c == 'g') {
drawLine(dest, x, y, xleft, y);
drawLine(dest, x, y, x, ybottom);
}
}
}
ImageIO.write(dest, "png", new File("output.png"));
}
private static void drawLine(BufferedImage dest, int x1, int y1, int x2, int y2) {
int dist = Math.max(Math.abs(x1 - x2), Math.abs(y1 - y2));
for (int i = 0; i <= dist; i++) {
int x = (x1*(dist - i) + x2 * i) / dist;
int y = (y1*(dist - i) + y2 * i) / dist;
dest.getRaster().setPixel(x, y, new int [] {0, 0, 0});
}
}
private static void expand(BufferedImage src, List<String> tab, String p1, String p2, String r1, String r2, boolean choose) {
for (int k = 0; k < (choose ? 2 : 1); k++) {
while (true) {
boolean again = false;
for (int j = 0; j < tab.size() - 1; j++) {
String line1 = tab.get(j);
String line2 = tab.get(j+1);
int baseScore = evaluateLine(src, j, tab.size(), line1) + evaluateLine(src, j+1, tab.size(), line2);
for (int i = 0; i <= line1.length() - p1.length(); i++) {
if (line1.substring(i, i + p1.length()).equals(p1)
&& line2.substring(i, i + p2.length()).equals(p2)) {
String nline1 = line1.substring(0, i) + r1 + line1.substring(i + p1.length());
String nline2 = line2.substring(0, i) + r2 + line2.substring(i + p2.length());
int nScore = evaluateLine(src, j, tab.size(), nline1) + evaluateLine(src, j+1, tab.size(), nline2);
if (!choose || nScore > baseScore) {
tab.set(j, nline1);
tab.set(j+1, nline2);
again = true;
break;
}
}
}
if (again) break;
}
if (!again) break;
}
String tmp1 = r1;
String tmp2 = r2;
r1 = p1;
r2 = p2;
p1 = tmp1;
p2 = tmp2;
}
}
private static int evaluateLine(BufferedImage src, int j, int tabSize, String line) {
int [] color = {0, 0, 0};
int score = 0;
for (int i = 0; i < line.length(); i++) {
char c = line.charAt(i);
int x = i*src.getWidth() / line.length();
int y = j*src.getHeight() / tabSize;
src.getRaster().getPixel(x, y, color);
if (c == ' ' && color[0] >= 128) score++;
if (c != ' ' && color[0] < 128) score++;
}
return score;
}
private static List<String> iterate(BufferedImage src, List<String> tab, boolean choose) {
int [] color = {0, 0, 0};
List<String> tab2 = new ArrayList<String>();
for (int j = 0; j < tab.size(); j++) {
String line = tab.get(j);
String l1 = "", l2 = "", l3 = "";
for (int i = 0; i < line.length(); i++) {
char c = line.charAt(i);
List<String []> candidates = replace(c);
String [] choice = null;
if (choose) {
int best = 0;
for (String [] candidate : candidates) {
int bright1 = 0;
int bright2 = 0;
for (int j1 = 0; j1<3; j1++) {
int y = j*3+j1;
for (int i1 = 0; i1<3; i1++) {
int x = i*3+i1;
char c2 = candidate[j1].charAt(i1);
src.getRaster().getPixel(x*src.getWidth()/(line.length()*3), y*src.getHeight()/(tab.size()*3), color);
if (c2 != ' ') bright1++;
if (color[0] > 128) bright2++;
}
}
int score = Math.abs(bright1 - bright2);
if (choice == null || score > best) {
best = score;
choice = candidate;
}
}
} else {
choice = candidates.get(0);
}
//String [] r = candidates.get(rand.nextInt(candidates.size()));
String [] r = choice;
l1 += r[0];
l2 += r[1];
l3 += r[2];
}
tab2.add(l1);
tab2.add(l2);
tab2.add(l3);
}
return tab2;
}
private static List<String []> replace(char c) {
if (c == 'r') {
return Arrays.asList(
new String[] {
"r-g",
"| L",
"Lg "},
new String[] {
" ",
" r-",
" | "},
new String[] {
" ",
"r--",
"Lg "},
new String[] {
" rg",
" |L",
" | "},
new String[] {
" ",
" r",
" rJ"});
} else if (c == 'g') {
return Arrays.asList(
new String[] {
"r-g",
"J |",
" rJ"},
new String[] {
" ",
"-g ",
" | "},
new String[] {
" ",
"--g",
" rJ"},
new String[] {
"rg ",
"J| ",
" | "},
new String[] {
" ",
"g ",
"Lg "});
} else if (c == 'L') {
return Arrays.asList(
new String[] {
"rJ ",
"| r",
"L-J"},
new String[] {
" | ",
" L-",
" "},
new String[] {
"rJ ",
"L--",
" "},
new String[] {
" | ",
" |r",
" LJ"},
new String[] {
" Lg",
" L",
" "});
} else if (c == 'J') {
return Arrays.asList(
new String[] {
" Lg",
"g |",
"L-J"},
new String[] {
" | ",
"-J ",
" "},
new String[] {
" Lg",
"--J",
" "},
new String[] {
" | ",
"g| ",
"LJ "},
new String[] {
"rJ ",
"J ",
" "});
} else if (c == '-') {
return Arrays.asList(
new String[] {
" rg",
"g|L",
"LJ "},
new String[] {
"rg ",
"J|r",
" LJ"},
new String[] {
" ",
"---",
" "},
new String[] {
"r-g",
"J L",
" "},
new String[] {
" ",
"g r",
"L-J"},
new String[] {
"rg ",
"JL-",
" "},
new String[] {
" rg",
"-JL",
" "},
new String[] {
" ",
"gr-",
"LJ "},
new String[] {
" ",
"-gr",
" LJ"}
);
} else if (c == '|') {
return Arrays.asList(
new String[] {
" Lg",
"r-J",
"Lg "},
new String[] {
"rJ ",
"L-g",
" rJ"},
new String[] {
" | ",
" | ",
" | "},
new String[] {
" Lg",
" |",
" rJ"},
new String[] {
"rJ ",
"| ",
"Lg "},
new String[] {
" Lg",
" rJ",
" | "},
new String[] {
" | ",
" Lg",
" rJ"},
new String[] {
"rJ ",
"Lg ",
" | "},
new String[] {
" | ",
"rJ ",
"Lg "}
);
} else {
List<String []> ret = new ArrayList<String []>();
ret.add(
new String[] {
" ",
" ",
" "});
return ret;
}
}
}