Ява, 1204 1132 1087 1076
Просто довести собі, що я можу це зробити.
Я включив імпорт поруч із деклараціями про функції; вони повинні бути поза класом, щоб це працювало:
import java.awt.*;import java.awt.image.*;import java.io.*;import java.util.*;import javax.imageio.*;
BufferedImage i;Set<Point>Q;void p(String a)throws Exception{i=new BufferedImage(302,302,1);i.getGraphics().drawImage(ImageIO.read(new File(a)),1,1,null);Set<Set<Point>>S=new HashSet<>();for(int y=0;y<300;y++){for(int x=0;x<300;x++){if(!G(x,y)){Point p=new Point(x,y);Q=new HashSet<>();if(!S.stream().anyMatch(s->s.contains(p)))S.add(f(x,y));}}}Object[]o=S.stream().sorted((p,P)->c(p)-c(P)).toArray();s(o[0],255);s(o[1],255<<16);s(o[2],0xFF00);s(o[3],0xFFFF00);ImageIO.write(i.getSubimage(1,1,300,300),"png",new File(a));}boolean G(int x,int y){return i.getRGB(x,y)!=-1;}Set<Point>f(int x,int y){Point p=new Point(x,y);if(!Q.contains(p)&&!G(x,y)){Q.add(p);f(x-1,y);f(x+1,y);f(x,y-1);f(x,y+1);}return Q;}int c(Set<Point>s){return(int)s.stream().filter(p->G(p.x-2,p.y-1)||G(p.x-2,p.y+1)||G(p.x+1,p.y-2)||G(p.x-1,p.y-2)||G(p.x+2,p.y-1)||G(p.x+2,p.y+1)||G(p.x+1,p.y+2)||G(p.x-1,p.y+2)).count();}void s(Object o,int c){((Set<Point>)o).stream().forEach(p->{i.setRGB(p.x,p.y,c);});}
Необолочений (і працює, тобто додається котельня):
import java.awt.Point;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.HashSet;
import java.util.Set;
import javax.imageio.ImageIO;
public class SquareCircleTriangleGear {
public static void main(String[]args){
try {
new SquareCircleTriangleGear().p("filepath");
} catch (Exception ex) {
}
}
BufferedImage i;
Set<Point>Q;
void p(String a)throws Exception{
i = new BufferedImage(302,302,BufferedImage.TYPE_INT_RGB);
i.getGraphics().drawImage(ImageIO.read(new File(a)),1,1,null);
Set<Set<Point>>set=new HashSet<>();
for(int y=0;y<300;y++){
for(int x = 0;x<300;x++){
if(i.getRGB(x,y)==-1){
Point p = new Point(x,y);
Q=new HashSet<>();
if(!set.stream().anyMatch((s)->s.contains(p))){
set.add(fill(x,y));
}
}
}
}
Object[]o=set.stream().sorted((p,P)->c(p)-c(P)).toArray();
s(o[0],0x0000FF);
s(o[1],0xFF0000);
s(o[2],0x00FF00);
s(o[3],0xFFFF00);
ImageIO.write(i.getSubImage(1,1,300,300), "png", new File(a));
}
Set<Point>fill(int x, int y){
Point p=new Point(x,y);
if(!Q.contains(p)&&!i.getRGB(x,y)!=-1) {
Q.add(p);
fill(x-1,y);
fill(x+1,y);
fill(x,y-1);
fill(x,y+1);
}
return Q;
}
int c(Set<Point>s){return (int)s.stream().filter(p->isBoundary(p.x,p.y)).count();}
boolean isBoundary(int x, int y){
return i.getRGB(x-2,y-1)!=-1||i.getRGB(x-2,y+1)!=-1||i.getRGB(x+1,y-2)!=-1||
i.getRGB(x-1,y-2)!=-1||i.getRGB(x+2,y-1)!=-1||i.getRGB(x+2,y+1)!=-1||
i.getRGB(x+1,y+2)!=-1||i.getRGB(x-1,y+2)!=-1;
}
void s(Object o,int c){
((Set<Point>)o).stream().forEach(p->{i.setRGB(p.x,p.y,c);});
}
}
Це працює за допомогою ітерації над кожним пікселем зображення та заповненням заливів кожного разу, коли ми досягаємо "дірки". Додаємо кожен результат заливки як Set<Point>
а Set
. Потім ми визначаємо, яка форма, яка. Це робиться шляхом перегляду кількості граничних пікселів фігури. Я визначав межу як відступ лицаря від чорної плитки, оскільки це буде залишатися більш постійним між обертаннями та подібними. Коли ми це робимо, стає зрозуміло, що фігури можна сортувати за цим значенням: Коло, Квадрат, Трикутник, Шестірня. Тому я сортую і встановлюю всі пікселі такої форми до потрібного кольору.
Зауважте, що зображення, до якого я пишу, не береться безпосередньо з файлу, тому що якби я це зробив, Java ставилася б до зображення як до чорно-білого, а наповнення кольорами не працювало. Тому я маю створити власний образ за допомогою TYPE_INT_RGB
(що є 1
). Також зверніть увагу , що зображення , яке я роблю роботу на це 302
шляхом 302
; це так, що алгоритму дистанції Найт не потрібно турбуватися про спробу читання поза межами зображення. Цю невідповідність за розміром я виправляю за допомогою дзвінка i.getSubImage(1,1,300,300)
. Примітка. Можливо, я забув виправити це, коли завантажував зображення, у цих випадках зображення занадто широкі на 2 пікселі, але, крім цього факту, вони повинні бути правильними
Функція замінить файл, шлях якого передано. Виходи: