Initial sharing of project
|
@ -0,0 +1,81 @@
|
|||
import java.util.ArrayList;
|
||||
import java.io.File;
|
||||
import java.awt.Color;
|
||||
import java.awt.image.BufferedImage;
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
/**
|
||||
* Beschreiben Sie hier die Klasse Image.
|
||||
*
|
||||
* @author Alexander Kimmig
|
||||
* @version 1.0
|
||||
*/
|
||||
public class Image
|
||||
{
|
||||
/**
|
||||
* Liest eine JPG-Bilddatei ein und gibt diese als ArrayList von RGB-Objekten zurück
|
||||
*
|
||||
* @param filename Dateiname die eingelesen werden soll
|
||||
* @return ArrayList<RGB> der einzelnen Pixelwerte
|
||||
* @throws Exception
|
||||
*/
|
||||
public static ArrayList<RGB> readFile(String filename) throws Exception {
|
||||
ArrayList<RGB> points = new ArrayList<>();
|
||||
|
||||
File file= new File(filename);
|
||||
BufferedImage img = ImageIO.read(file);
|
||||
for (int y = 0; y < img.getHeight(); y++) {
|
||||
for (int x = 0; x < img.getWidth(); x++) {
|
||||
points.add(new RGB(img.getRGB(x,y)));
|
||||
}
|
||||
}
|
||||
|
||||
return points;
|
||||
}
|
||||
|
||||
/**
|
||||
* Schreibt die RGB-Daten in eine Datei
|
||||
*
|
||||
* @param input Dateiname der ursprünglichen Datei (wird für Dimensionen gebraucht)
|
||||
* @param output Dateiname der neuen Datei
|
||||
* @param data RGB-Daten der einzelnen Pixel
|
||||
*/
|
||||
public static void writeFile(String input, String output, ArrayList<RGB> data) throws Exception {
|
||||
File file = new File(input);
|
||||
BufferedImage img = ImageIO.read(file);
|
||||
|
||||
int w = img.getWidth();
|
||||
int y = 0, x = 0;
|
||||
for (RGB p : data) {
|
||||
img.setRGB(x, y, p.toInt());
|
||||
if (++x >= w) {
|
||||
x = 0;
|
||||
++y;
|
||||
}
|
||||
}
|
||||
|
||||
File f = new File(output);
|
||||
ImageIO.write(img, "jpg", f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schreibt die RGB-Daten in eine Datei anhand der Quantifizierungs-Punkte
|
||||
* Jeder Pixel bekommt die Farbe des nächstliegenden Quantifizierungs-Punktes.
|
||||
*
|
||||
* @param input Dateiname der ursprünglichen Datei (wird für Dimensionen gebraucht)
|
||||
* @param output Dateiname der neuen Datei
|
||||
* @param data RGB-Daten der einzelnen Pixel
|
||||
* @param quants Quantifizierungs-Punkte
|
||||
*/
|
||||
public static void writeFile(String input, String target, ArrayList<RGB> data, ArrayList<RGB> quants) throws Exception {
|
||||
ArrayList<RGB> q = new ArrayList<>();
|
||||
|
||||
// Mappe punkte auf quantifizierte Punkte
|
||||
for (RGB p : data) {
|
||||
q.add(Quant.findNearest(quants, p));
|
||||
}
|
||||
|
||||
// schreibe Datei
|
||||
writeFile(input, target, q);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,200 @@
|
|||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* Funktionen, um quantifizierungs-Punkte zu finden
|
||||
*
|
||||
* @author Alexander Kimmig
|
||||
* @version 1.0
|
||||
*/
|
||||
public class Quant
|
||||
{
|
||||
/**
|
||||
* Führt eine vollständige RGB-Qunatfizierung durch, Lädt die Datei
|
||||
* input.jpg im Projektordner und speichert das Ergebnis in output.jpg
|
||||
*
|
||||
* @param count Anzahl, wie viele Quantifizierungs-Punkte gefunden werden solle
|
||||
* @param epoch Anzahl, wie viele Epochen durchlaufen werden sollen
|
||||
* @throws Exception falls Datei nicht existiert
|
||||
*/
|
||||
public static void quantize(int count, int epoch) throws Exception {
|
||||
ArrayList<RGB> ipoints = Image.readFile("./input.jpg");
|
||||
|
||||
ArrayList<RGB> quants = findQuants(count, epoch, ipoints);
|
||||
|
||||
for (int i = 0; i < ipoints.size(); i++) {
|
||||
RGB p = ipoints.get(i);
|
||||
RGB t = findNearest(quants, p);
|
||||
p.r = t.r;
|
||||
p.g = t.g;
|
||||
p.b = t.b;
|
||||
}
|
||||
|
||||
Image.writeFile("./input.jpg", "./output.jpg", ipoints);
|
||||
}
|
||||
|
||||
/**
|
||||
* Findet Quantenpunkte
|
||||
*
|
||||
* @param count Anzahl, wie viele Quantifizierungs-Punkte gefunden werden solle
|
||||
* @param epoch Anzahl, wie viele Epochen durchlaufen werden sollen
|
||||
* @param ipoints RGB-Datenpunkte des Bildes
|
||||
*
|
||||
* @return ArrayList<RGB> mit den Quantenpunkten
|
||||
* @throws Exception falls Datei nicht existiert
|
||||
*/
|
||||
public static ArrayList<RGB> findQuants(int count, int epoch, ArrayList<RGB> ipoints) throws Exception {
|
||||
ArrayList<RGB> qpoints = new ArrayList<>();
|
||||
|
||||
// Füge neue, zufällige Punkte hinzu
|
||||
for (int i = 0; i < count; i++) {
|
||||
qpoints.add(new RGB(true));
|
||||
}
|
||||
|
||||
for (int i = 0; i < epoch; i++) {
|
||||
// Epoche durchlaufen
|
||||
doEpoch(ipoints, qpoints);
|
||||
// nich bewegte Quantenpunkte versetzen
|
||||
if (i < epoch-1) resetQuants(qpoints);
|
||||
}
|
||||
|
||||
return qpoints;
|
||||
}
|
||||
|
||||
/**
|
||||
* Epoche durchlaufen
|
||||
*
|
||||
* @param ipoints RGB-Bildpunkte
|
||||
* @param qpoints bisherige Quantenpunkte -> werden direkt verändert
|
||||
*/
|
||||
public static void doEpoch(ArrayList<RGB> ipoints, ArrayList<RGB> qpoints) {
|
||||
/*
|
||||
* WICHTIG: Bildpunkte mischen, da ansonsten die Punkte linear durchgegangen werden.
|
||||
* Bei großen Flächen am Ende (rechts unten) werden sonst viele Quantenpunkte in diesen
|
||||
* Bereich gezogen
|
||||
*
|
||||
* Ausprobieren: deaktivieren und das Beispielbild "sonnenaufgang"
|
||||
*/
|
||||
Collections.shuffle(ipoints);
|
||||
|
||||
/*
|
||||
* Eine Epoche: alle Bildpunkte einmal durchlaufen
|
||||
*/
|
||||
for (RGB t : ipoints) {
|
||||
// jeweils den nächstliegenden Quantenpunkt finden
|
||||
RGB q = findNearest(qpoints, t);
|
||||
|
||||
// gegangener Weg speichern
|
||||
q.walk += t.diff2(q);
|
||||
q.count++;
|
||||
|
||||
// den Punkt verschieben
|
||||
q.r = (q.r + t.r) / 2;
|
||||
q.g = (q.g + t.g) / 2;
|
||||
q.b = (q.b + t.b) / 2;
|
||||
}
|
||||
|
||||
for (RGB tmp : qpoints) {
|
||||
// falls Punkt verschoben: berechne mittlere gegangene Weglänge
|
||||
if (tmp.count > 0) {
|
||||
tmp.walk = Math.max(1, tmp.walk / tmp.count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Versetzt die Quantenpunkte, die im letzten Schritt nicht versetzt wurden, d.h.
|
||||
* diejenigen, die zu weit von der Punktwolke entfernt sind.
|
||||
*
|
||||
* Hierfür setze diejenigen, die nicht gegangen sind in die Nähe derjeniger Punkte,
|
||||
* die besonders weit gelaufen sind (da dort ggf. underfitted)
|
||||
*
|
||||
* @param qpoints Quantenpunkte
|
||||
* @return int wie viele Punkte wurden versetzt
|
||||
*/
|
||||
public static int resetQuants(ArrayList<RGB> qpoints) {
|
||||
int reset = 0;
|
||||
for (int i = 0; i < qpoints.size(); i++) {
|
||||
// finde denjenigen Punkt, der am wenigsten gelaufen ist
|
||||
RGB min = findMinWalk(qpoints);
|
||||
// wenn es keinen gibt oder dieser auch weit gelaufen ist, dann breche ab
|
||||
if (min == null || min.walk > 5) break;
|
||||
|
||||
// finde denjenigen, der am weitesten gelaufen ist (dessen Bereich underfitted ist)
|
||||
RGB max = findMaxWalk(qpoints);
|
||||
// breche ab, falls dieser insgesamt auch sehr wenig gelaufen ist
|
||||
if (max.walk < 25) break;
|
||||
|
||||
// passe den Wert an, damit dieser beim nächsten Schleifendurchlauf nicht mehr direkt gefunden wird
|
||||
max.walk -= 36;
|
||||
|
||||
// setze den Nichtläufer zum Weitläufer
|
||||
min.setTo(max);
|
||||
// und variiere dessen Positionen um maximal ±5
|
||||
min.jitter(5);
|
||||
// walk = -1 -> nicht mehr weiter in diesem Durchlauf betrachten (nicht mehr als Minimum finden)
|
||||
min.walk = -1;
|
||||
// zähle die Anzahl der versetzten Punkte
|
||||
reset++;
|
||||
}
|
||||
|
||||
// setze gelaufene Wege aller Punkte zurück
|
||||
for (RGB q : qpoints) {
|
||||
q.walk = q.count = 0;
|
||||
}
|
||||
|
||||
return reset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finde denjenigen Punkt in der Liste, der am wenigsten weit gelaufen ist
|
||||
*
|
||||
* @param quants Punktliste
|
||||
* @return RGB der Punkt, der am wenigsten gelaufen ist oder null
|
||||
*/
|
||||
private static RGB findMinWalk(ArrayList<RGB> quants) {
|
||||
RGB min = null;
|
||||
for (RGB tmp : quants) {
|
||||
if (tmp.walk >= 0 && (min == null || tmp.walk < min.walk)) {
|
||||
min = tmp;
|
||||
}
|
||||
}
|
||||
return min;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finde denjenigen Punkt in der Liste, der am weitesten gelaufen ist
|
||||
*
|
||||
* @param quants Punktliste
|
||||
* @return RGB der Punkt, der am weitesten gelaufen ist
|
||||
*/
|
||||
private static RGB findMaxWalk(ArrayList<RGB> quants) {
|
||||
RGB max = quants.get(0);
|
||||
for (RGB q : quants) {
|
||||
if (q.walk > max.walk) max = q;
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finde den Punkt in der Liste der die kürzeste Distanz zum Zielpunkt hat
|
||||
*
|
||||
* @param points Liste der Punkte
|
||||
* @param target Zielpunkt
|
||||
* @return RGB Punkt mit kürzestem Abstand
|
||||
*/
|
||||
public static RGB findNearest(ArrayList<RGB> points, RGB target) {
|
||||
RGB nearest = points.get(0);
|
||||
int mind = target.diff2(nearest);
|
||||
|
||||
for (RGB p : points) {
|
||||
int d = target.diff2(p);
|
||||
if (d < mind) {
|
||||
nearest = p;
|
||||
mind = d;
|
||||
}
|
||||
}
|
||||
|
||||
return nearest;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
------------------------------------------------------------------------
|
||||
Dies ist die README-Datei des Projekts. Hier sollten Sie Ihr Projekt
|
||||
beschreiben.
|
||||
Erzählen Sie dem Leser (jemand, der nichts über dieses Projekt weiss),
|
||||
alles, was er/sie wissen muss. Üblicherweise sollte der Kommentar
|
||||
zumindest die folgenden Angaben umfassen:
|
||||
------------------------------------------------------------------------
|
||||
|
||||
PROJEKTBEZEICHNUNG:
|
||||
PROJEKTZWECK:
|
||||
VERSION oder DATUM:
|
||||
WIE IST DAS PROJEKT ZU STARTEN:
|
||||
AUTOR(EN):
|
||||
BENUTZERHINWEISE:
|
|
@ -0,0 +1,161 @@
|
|||
import java.awt.Color;
|
||||
|
||||
/**
|
||||
* Repräsentiert einen Punkt im RGB-Raum
|
||||
*
|
||||
* @author Alexander Kimmig
|
||||
* @version 1.0
|
||||
*/
|
||||
public class RGB
|
||||
{
|
||||
/**
|
||||
* Rot-Anteil 0-255
|
||||
*/
|
||||
public int r;
|
||||
|
||||
/**
|
||||
* Grün-Anteil 0-255
|
||||
*/
|
||||
public int g;
|
||||
|
||||
/**
|
||||
* Blau-Anteil 0-255
|
||||
*/
|
||||
public int b;
|
||||
|
||||
/**
|
||||
* Wie weit ist der Punkt in der letzten Epoche gelaufen
|
||||
*/
|
||||
public int walk;
|
||||
|
||||
/**
|
||||
* Wie oft ist der Punkt in der letzten Epoche gelaufen
|
||||
*/
|
||||
public int count;
|
||||
|
||||
/**
|
||||
* Konstruktor
|
||||
*
|
||||
* @param random Punkt zufällig setzen
|
||||
*/
|
||||
public RGB(boolean random) {
|
||||
this(0, 0, 0);
|
||||
|
||||
if (random) this.setRandom();
|
||||
}
|
||||
|
||||
/**
|
||||
* Konstruktor
|
||||
*
|
||||
* @param c ein awt.Color-Wert
|
||||
*/
|
||||
public RGB(Color c) {
|
||||
this(c.getRed(), c.getGreen(), c.getBlue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Konstruktor
|
||||
*
|
||||
* @param c ein int-Wert 0xRRGGBB
|
||||
*/
|
||||
public RGB(int c) {
|
||||
this(c >> 16 & 0xFF, c >> 8 & 0xFF, c & 0xFF);
|
||||
}
|
||||
|
||||
/**
|
||||
* Konstruktor
|
||||
*
|
||||
* @param r Rot-Anteil 0-255
|
||||
* @param g Grün-Anteil 0-255
|
||||
* @param b Blau-Anteil 0-255
|
||||
*/
|
||||
public RGB(int r, int g, int b) {
|
||||
this.r = Math.min(255, Math.max(0, r));
|
||||
this.g = Math.min(255, Math.max(0, g));
|
||||
this.b = Math.min(255, Math.max(0, b));
|
||||
|
||||
this.walk = 0;
|
||||
this.count = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Kopier-Konstruktor
|
||||
*/
|
||||
public RGB(RGB copy) {
|
||||
this(copy.r, copy.g, copy.b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ausgabe als String
|
||||
*
|
||||
* @return String: "R, G, B"
|
||||
*/
|
||||
public String toString() {
|
||||
return this.r + "," + this.g + "," + this.b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ausgabe als awt.Color
|
||||
*
|
||||
* @return awt.Color
|
||||
*/
|
||||
public Color toColor() {
|
||||
return new Color(this.r, this.g, this.b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ausgabe als int
|
||||
*/
|
||||
public int toInt() {
|
||||
return (this.r << 16) + (this.g << 8) + (this.b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setze zufällige Koordinaten
|
||||
*/
|
||||
public void setRandom() {
|
||||
this.r = (int)(Math.random() * 256);
|
||||
this.g = (int)(Math.random() * 256);
|
||||
this.b = (int)(Math.random() * 256);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setze Koordinaten
|
||||
*/
|
||||
public void setTo(RGB p) {
|
||||
this.r = p.r;
|
||||
this.g = p.g;
|
||||
this.b = p.b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Variiere Koordinaten ±max
|
||||
*
|
||||
* @param max maximale verschiebung pro Achse
|
||||
*/
|
||||
public void jitter(int max) {
|
||||
this.r = Math.min(255, Math.max(0, this.r + ((int)(Math.random() * max * 2 - max))));
|
||||
this.g = Math.min(255, Math.max(0, this.g + ((int)(Math.random() * max * 2 - max))));
|
||||
this.b = Math.min(255, Math.max(0, this.b + ((int)(Math.random() * max * 2 - max))));
|
||||
}
|
||||
|
||||
/**
|
||||
* Berechne den quadratischen Abstand zweier Punkte
|
||||
*
|
||||
* @param a erster Punkt
|
||||
* @param b zweiter Punkt
|
||||
*/
|
||||
public static int diff2(RGB a, RGB b) {
|
||||
int dr = a.r - b.r;
|
||||
int dg = a.g - b.g;
|
||||
int db = a.b - b.b;
|
||||
return dr*dr + dg*dg + db*db;
|
||||
}
|
||||
|
||||
/**
|
||||
* Berechne den quadratischen Abstand zu einem anderen Punkt
|
||||
*/
|
||||
public int diff2(RGB b) {
|
||||
return RGB.diff2(this, b);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,251 @@
|
|||
import ChartDirector.*;
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.util.ArrayList;
|
||||
import java.io.File;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* Zeigt das Fenster an mit allen Komponenten
|
||||
*
|
||||
* @author Alexander Kimmig
|
||||
* @version 1.0
|
||||
*/
|
||||
public class Window implements ActionListener
|
||||
{
|
||||
private JFrame frame;
|
||||
private JPanel drawPanel;
|
||||
|
||||
private ArrayList<RGB> image;
|
||||
private ArrayList<RGB> orig;
|
||||
private ArrayList<RGB> quants;
|
||||
|
||||
private int alpha = 25;
|
||||
private int beta = 45;
|
||||
|
||||
private JButton vl;
|
||||
private JButton vr;
|
||||
private JButton vu;
|
||||
private JButton vd;
|
||||
|
||||
private JButton b_load;
|
||||
private JButton b_gen;
|
||||
private JButton b_epoc;
|
||||
private JButton b_reset;
|
||||
private JButton b_save;
|
||||
|
||||
private JComboBox s_input;
|
||||
private JTextField t_anz;
|
||||
private JTextField t_output;
|
||||
|
||||
/**
|
||||
* Konstruktor: legt JFrame und alle Panels/Buttons an
|
||||
*/
|
||||
public Window()
|
||||
{
|
||||
frame = new JFrame();
|
||||
frame.addWindowListener(new WindowAdapter() {
|
||||
public void windowClosing(WindowEvent e) { System.exit(0); }
|
||||
});
|
||||
|
||||
JPanel mainPanel = new JPanel();
|
||||
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
|
||||
|
||||
drawPanel = new JPanel();
|
||||
drawPanel.setPreferredSize(new Dimension(1000, 1000));
|
||||
drawPanel.setBackground(new Color(0xFFFFFF));
|
||||
JPanel view = new JPanel();
|
||||
JPanel steps = new JPanel();
|
||||
JPanel config = new JPanel();
|
||||
|
||||
mainPanel.add(drawPanel);
|
||||
mainPanel.add(view);
|
||||
mainPanel.add(steps);
|
||||
mainPanel.add(config);
|
||||
|
||||
vl = new JButton("<");
|
||||
vl.addActionListener(this);
|
||||
view.add(vl);
|
||||
vr = new JButton(">");
|
||||
vr.addActionListener(this);
|
||||
view.add(vr);
|
||||
vu = new JButton("^");
|
||||
vu.addActionListener(this);
|
||||
view.add(vu);
|
||||
vd = new JButton("v");
|
||||
vd.addActionListener(this);
|
||||
view.add(vd);
|
||||
|
||||
b_load = new JButton("Datei laden");
|
||||
b_load.addActionListener(this);
|
||||
steps.add(b_load);
|
||||
|
||||
b_gen = new JButton("Zufällige Punkte erzeugen");
|
||||
b_gen.addActionListener(this);
|
||||
steps.add(b_gen);
|
||||
|
||||
b_epoc = new JButton("Epoche durchspielen");
|
||||
b_epoc.addActionListener(this);
|
||||
steps.add(b_epoc);
|
||||
|
||||
b_reset = new JButton("Punkte versetzen");
|
||||
b_reset.addActionListener(this);
|
||||
steps.add(b_reset);
|
||||
|
||||
b_save = new JButton("Datei speichern");
|
||||
b_save.addActionListener(this);
|
||||
steps.add(b_save);
|
||||
|
||||
config.add(new JLabel("Input:"));
|
||||
s_input = new JComboBox(getJPGs());
|
||||
config.add(s_input);
|
||||
|
||||
config.add(new JLabel("Anzahl Punkte:"));
|
||||
t_anz = new JTextField("32");
|
||||
t_anz.setPreferredSize(new Dimension(100,20));
|
||||
config.add(t_anz);
|
||||
|
||||
config.add(new JLabel("Output:"));
|
||||
t_output = new JTextField("output.jpg");
|
||||
t_output.setPreferredSize(new Dimension(100,20));
|
||||
config.add(t_output);
|
||||
|
||||
frame.add(mainPanel);
|
||||
|
||||
frame.pack();
|
||||
frame.setVisible(true);
|
||||
|
||||
this.image = new ArrayList<>();
|
||||
this.quants = new ArrayList<>();
|
||||
|
||||
this.plot();
|
||||
}
|
||||
|
||||
/**
|
||||
* plottet die Punkte in ein 3D-Scatter-Plot und zeigt dieses an
|
||||
*/
|
||||
public void plot()
|
||||
{
|
||||
ChartViewer viewer = new ChartViewer();
|
||||
|
||||
// Einstellungen setzen
|
||||
ThreeDScatterChart c = new ThreeDScatterChart(1000, 1000);
|
||||
c.setPlotRegion(500, 480, 600, 600, 450);
|
||||
c.xAxis().setTitle("R", "Arial Bold", 10);
|
||||
c.yAxis().setTitle("G", "Arial Bold", 10);
|
||||
c.zAxis().setTitle("B", "Arial Bold", 10);
|
||||
c.xAxis().setDateScale(0, 255);
|
||||
c.yAxis().setDateScale(0, 255);
|
||||
c.zAxis().setDateScale(0, 255);
|
||||
c.setViewAngle(alpha, beta);
|
||||
|
||||
// Bildpunkte
|
||||
double[] x = new double[image.size()];
|
||||
double[] y = new double[image.size()];
|
||||
double[] z = new double[image.size()];
|
||||
for (int i = 0; i < image.size(); i++) {
|
||||
x[i] = image.get(i).r;
|
||||
y[i] = image.get(i).g;
|
||||
z[i] = image.get(i).b;
|
||||
}
|
||||
// Koordinaten Form Größe Farbe ARGB Rahmen ARGB
|
||||
c.addScatterGroup(x,y,z, "", Chart.CircleShape, 5, 0xE0FF0000, 0xFF000000);
|
||||
|
||||
// Quantenpunkte
|
||||
x = new double[quants.size()];
|
||||
y = new double[quants.size()];
|
||||
z = new double[quants.size()];
|
||||
for (int i = 0; i < quants.size(); i++) {
|
||||
x[i] = quants.get(i).r;
|
||||
y[i] = quants.get(i).g;
|
||||
z[i] = quants.get(i).b;
|
||||
}
|
||||
c.addScatterGroup(x,y,z, "", Chart.CircleShape, 12);
|
||||
|
||||
viewer.setChart(c);
|
||||
|
||||
drawPanel.removeAll();
|
||||
drawPanel.add(viewer);
|
||||
|
||||
frame.pack();
|
||||
}
|
||||
|
||||
/**
|
||||
* Lies die vorhandenen JPG-Dateien aus dem Ordner inputs aus
|
||||
*
|
||||
* @return String[] Dateinamen
|
||||
*/
|
||||
private String[] getJPGs() {
|
||||
ArrayList<String> result = new ArrayList<String>();
|
||||
|
||||
File d = new File("./inputs/");
|
||||
File[] list = d.listFiles();
|
||||
for(int i=0; i<list.length; i++) {
|
||||
String n = list[i].getName();
|
||||
// nur JPG-Bilder
|
||||
if (n.matches(".*\\.[jJ][pP][eE]?[gG]$")) {
|
||||
result.add(n);
|
||||
}
|
||||
}
|
||||
|
||||
String[] ret = new String[result.size()];
|
||||
return result.toArray(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* Button-Reaktivität
|
||||
*
|
||||
* @param e ActionEvent
|
||||
*/
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
/**
|
||||
* Pfeilbuttons: Ändern der Ansicht
|
||||
*/
|
||||
if (e.getSource() == this.vr) beta = (beta + 345) % 360;
|
||||
if (e.getSource() == this.vl) beta = (beta + 15) % 360;
|
||||
if (e.getSource() == this.vu) alpha = (alpha + 345) % 360;
|
||||
if (e.getSource() == this.vd) alpha = (alpha + 15) % 360;
|
||||
|
||||
/**
|
||||
* Datei laden und RGB-Daten in ArrayList speichern
|
||||
*/
|
||||
if (e.getSource() == this.b_load) {
|
||||
try {
|
||||
this.orig = Image.readFile("./inputs/" + (String)this.s_input.getSelectedItem());
|
||||
for (RGB p : this.orig) {
|
||||
// kopiere die originalen Daten, damit die Liste später gemischt werden kann
|
||||
this.image.add(p);
|
||||
}
|
||||
} catch (Exception ex) {}
|
||||
}
|
||||
/**
|
||||
* Zufällige Punkte erzeugen
|
||||
*/
|
||||
if (e.getSource() == this.b_gen) {
|
||||
this.quants = new ArrayList<>();
|
||||
for (int i = 0; i < Integer.parseInt(this.t_anz.getText()); i++) {
|
||||
this.quants.add(new RGB(true));
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Epoche durchlaufen
|
||||
*/
|
||||
if (e.getSource() == this.b_epoc) Quant.doEpoch(this.image, this.quants);
|
||||
/**
|
||||
* Nicht bewegte Punkte versetzen
|
||||
*/
|
||||
if (e.getSource() == this.b_reset) Quant.resetQuants(this.quants);
|
||||
/**
|
||||
* quantifiziertes Bild speichern
|
||||
*/
|
||||
if (e.getSource() == this.b_save) {
|
||||
try {
|
||||
Image.writeFile("./inputs/" + (String)this.s_input.getSelectedItem(), "./outputs/" + this.t_output.getText(), this.orig, this.quants);
|
||||
} catch (Exception ex) {}
|
||||
}
|
||||
|
||||
// neue Anzeige rendern
|
||||
this.plot();
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 145 KiB |
After Width: | Height: | Size: 72 KiB |
After Width: | Height: | Size: 204 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 122 KiB |
After Width: | Height: | Size: 43 KiB |
After Width: | Height: | Size: 63 KiB |
After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 88 KiB |
After Width: | Height: | Size: 88 KiB |
After Width: | Height: | Size: 45 KiB |
After Width: | Height: | Size: 64 KiB |
After Width: | Height: | Size: 62 KiB |
After Width: | Height: | Size: 70 KiB |
After Width: | Height: | Size: 78 KiB |
After Width: | Height: | Size: 86 KiB |
After Width: | Height: | Size: 56 KiB |
After Width: | Height: | Size: 57 KiB |
After Width: | Height: | Size: 47 KiB |
After Width: | Height: | Size: 54 KiB |
After Width: | Height: | Size: 1.4 MiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 12 KiB |
|
@ -0,0 +1,74 @@
|
|||
#BlueJ package file
|
||||
dependency1.from=Image
|
||||
dependency1.to=RGB
|
||||
dependency1.type=UsesDependency
|
||||
dependency2.from=Image
|
||||
dependency2.to=Quant
|
||||
dependency2.type=UsesDependency
|
||||
dependency3.from=Quant
|
||||
dependency3.to=RGB
|
||||
dependency3.type=UsesDependency
|
||||
dependency4.from=Quant
|
||||
dependency4.to=Image
|
||||
dependency4.type=UsesDependency
|
||||
dependency5.from=Window
|
||||
dependency5.to=RGB
|
||||
dependency5.type=UsesDependency
|
||||
dependency6.from=Window
|
||||
dependency6.to=Image
|
||||
dependency6.type=UsesDependency
|
||||
dependency7.from=Window
|
||||
dependency7.to=Quant
|
||||
dependency7.type=UsesDependency
|
||||
editor.fx.0.height=0
|
||||
editor.fx.0.width=0
|
||||
editor.fx.0.x=0
|
||||
editor.fx.0.y=0
|
||||
objectbench.height=100
|
||||
objectbench.width=595
|
||||
package.divider.horizontal=0.599601593625498
|
||||
package.divider.vertical=0.8102836879432624
|
||||
package.editor.height=450
|
||||
package.editor.width=885
|
||||
package.editor.x=0
|
||||
package.editor.y=25
|
||||
package.frame.height=628
|
||||
package.frame.width=1024
|
||||
package.numDependencies=7
|
||||
package.numTargets=4
|
||||
package.showExtends=true
|
||||
package.showUses=true
|
||||
project.charset=UTF-8
|
||||
readme.height=60
|
||||
readme.name=@README
|
||||
readme.width=48
|
||||
readme.x=10
|
||||
readme.y=10
|
||||
target1.height=70
|
||||
target1.name=Window
|
||||
target1.showInterface=false
|
||||
target1.type=ClassTarget
|
||||
target1.width=120
|
||||
target1.x=150
|
||||
target1.y=280
|
||||
target2.height=70
|
||||
target2.name=Image
|
||||
target2.showInterface=false
|
||||
target2.type=ClassTarget
|
||||
target2.width=120
|
||||
target2.x=320
|
||||
target2.y=190
|
||||
target3.height=70
|
||||
target3.name=RGB
|
||||
target3.showInterface=false
|
||||
target3.type=ClassTarget
|
||||
target3.width=120
|
||||
target3.x=320
|
||||
target3.y=10
|
||||
target4.height=70
|
||||
target4.name=Quant
|
||||
target4.showInterface=false
|
||||
target4.type=ClassTarget
|
||||
target4.width=120
|
||||
target4.x=460
|
||||
target4.y=100
|