399 lines
12 KiB
Java
399 lines
12 KiB
Java
import com.jogamp.opengl.GL2;
|
|
import com.jogamp.opengl.glu.GLU;
|
|
import com.jogamp.opengl.GLAutoDrawable;
|
|
import com.jogamp.opengl.GLCapabilities;
|
|
import com.jogamp.opengl.GLEventListener;
|
|
import com.jogamp.opengl.GLProfile;
|
|
import com.jogamp.opengl.awt.GLCanvas;
|
|
|
|
import javax.swing.JFrame;
|
|
import java.awt.Color;
|
|
import java.awt.event.KeyListener;
|
|
import java.awt.event.KeyEvent;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import javax.swing.*;
|
|
import java.awt.*;
|
|
import java.awt.event.*;
|
|
import java.util.ArrayList;
|
|
import java.io.File;
|
|
import java.util.Collections;
|
|
|
|
import java.awt.image.BufferedImage;
|
|
|
|
public class OGL_Window implements GLEventListener, KeyListener, ActionListener {
|
|
private int imgHeight = 200;
|
|
|
|
private JFrame frame;
|
|
private JPanel drawPanel;
|
|
private JPanel drawImg;
|
|
private JPanel drawQImg;
|
|
|
|
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;
|
|
|
|
private final GLCanvas glcanvas;
|
|
|
|
private ArrayList<RGB> image;
|
|
private ArrayList<RGB> orig;
|
|
private ArrayList<RGB> quants;
|
|
|
|
private BufferedImage img;
|
|
private BufferedImage qimg;
|
|
|
|
private int azimut = 25;
|
|
private int rot = 45;
|
|
|
|
@Override
|
|
public void display(GLAutoDrawable drawable) {
|
|
final GL2 gl = drawable.getGL().getGL2();
|
|
|
|
gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT | GL2.GL_STENCIL_BUFFER_BIT);
|
|
|
|
final GLU glu = GLU.createGLU(gl);
|
|
gl.glMatrixMode(GL2.GL_PROJECTION);
|
|
gl.glLoadIdentity();
|
|
double w = this.drawPanel.getWidth();
|
|
double h = this.drawPanel.getHeight();
|
|
glu.gluPerspective(45,w/h,0.1,100);
|
|
gl.glMatrixMode(GL2.GL_MODELVIEW);
|
|
gl.glLoadIdentity();
|
|
glu.gluLookAt(
|
|
0,0,3,
|
|
0,0,0,
|
|
0,1,0
|
|
);
|
|
gl.glRotatef(this.azimut,1,0,0);
|
|
gl.glRotatef(-this.rot,0,1,0);
|
|
|
|
gl.glPointSize(20);
|
|
gl.glBegin(GL2.GL_POINTS);
|
|
gl.glColor4ub((byte)0,(byte)0,(byte)0,(byte)255);
|
|
gl.glVertex3f(0,0,0);
|
|
gl.glEnd();
|
|
|
|
gl.glLineWidth(5);
|
|
gl.glBegin(GL2.GL_LINES);
|
|
|
|
gl.glColor4f(0,0,0,1);
|
|
gl.glVertex3f(0,0,0);
|
|
gl.glColor4f(1,0,0,1);
|
|
gl.glVertex3f(1,0,0);
|
|
|
|
gl.glColor4f(0,0,0,1);
|
|
gl.glVertex3f(0,0,0);
|
|
gl.glColor4f(0,1,0,1);
|
|
gl.glVertex3f(0,1,0);
|
|
|
|
gl.glColor4f(0,0,0,1);
|
|
gl.glVertex3f(0,0,0);
|
|
gl.glColor4f(0,0,1,1);
|
|
gl.glVertex3f(0,0,1);
|
|
gl.glEnd();
|
|
|
|
gl.glEnable(GL2.GL_BLEND);
|
|
gl.glBlendFunc(GL2.GL_SRC_ALPHA, GL2.GL_ONE_MINUS_SRC_ALPHA);
|
|
|
|
gl.glPointSize(8);
|
|
gl.glBegin(GL2.GL_POINTS);
|
|
for (RGB p : this.image) {
|
|
gl.glColor4f(((float)(p.r))/256/4,((float)(p.g))/256/4,((float)(p.b))/256/4,0.15f);
|
|
gl.glVertex3f(
|
|
((float)(p.r))/256,
|
|
((float)(p.g))/256,
|
|
((float)(p.b))/256
|
|
);
|
|
}
|
|
gl.glEnd();
|
|
|
|
gl.glPointSize(20);
|
|
gl.glBegin(GL2.GL_POINTS);
|
|
for (RGB p : this.quants) {
|
|
gl.glColor4f(((float)(p.r))/256,((float)(p.g))/256,((float)(p.b))/256,1f);
|
|
gl.glVertex3f(
|
|
((float)(p.r))/256,
|
|
((float)(p.g))/256,
|
|
((float)(p.b))/256
|
|
);
|
|
}
|
|
gl.glEnd();
|
|
}
|
|
|
|
@Override
|
|
public void dispose(GLAutoDrawable arg0) {}
|
|
|
|
@Override
|
|
public void init(GLAutoDrawable drawable) {}
|
|
|
|
@Override
|
|
public void reshape(GLAutoDrawable drawable, int arg1, int arg2, int arg3, int arg4) {}
|
|
|
|
@Override
|
|
public void keyPressed(KeyEvent e) {}
|
|
|
|
@Override
|
|
public void keyTyped(KeyEvent e) {}
|
|
|
|
@Override
|
|
public void keyReleased(KeyEvent e) {
|
|
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
|
|
this.rot += 15;
|
|
} else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
|
|
this.rot -= 15;
|
|
} else if (e.getKeyCode() == KeyEvent.VK_UP) {
|
|
this.azimut -= 15;
|
|
} else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
|
|
this.azimut += 15;
|
|
} else {
|
|
return;
|
|
}
|
|
|
|
this.glcanvas.repaint();
|
|
}
|
|
|
|
private OGL_Window() {
|
|
this.image = new ArrayList<>();
|
|
this.orig = new ArrayList<>();
|
|
this.quants = new ArrayList<>();
|
|
|
|
//getting the capabilities object of GL2 profile
|
|
final GLProfile profile = GLProfile.get(GLProfile.GL2);
|
|
GLCapabilities capabilities = new GLCapabilities(profile);
|
|
capabilities.setBackgroundOpaque(false);
|
|
|
|
// The canvas
|
|
glcanvas = new GLCanvas(capabilities);
|
|
glcanvas.addGLEventListener(this);
|
|
glcanvas.setSize(500, 500);
|
|
glcanvas.setBackground(new Color(220, 220, 220));
|
|
glcanvas.addKeyListener(this);
|
|
|
|
OGL_Window that = this;
|
|
|
|
//creating frame
|
|
frame = new JFrame("RGB Quantisierer");
|
|
frame.addWindowListener(new WindowAdapter() {
|
|
public void windowClosing(WindowEvent e) { System.exit(0); }
|
|
});
|
|
frame.addComponentListener(new ComponentAdapter() {
|
|
public void componentResized(ComponentEvent e) {
|
|
int width = (int)that.frame.getSize().getWidth();
|
|
int height = (int)that.frame.getSize().getHeight() - 160 - that.imgHeight;
|
|
that.glcanvas.setSize(width, height);
|
|
that.drawPanel.setSize(new Dimension(width, height));
|
|
}
|
|
});
|
|
|
|
JPanel mainPanel = new JPanel();
|
|
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
|
|
|
|
drawPanel = new JPanel();
|
|
JPanel view = new JPanel();
|
|
JPanel steps = new JPanel();
|
|
JPanel config = new JPanel();
|
|
JPanel images = new JPanel();
|
|
|
|
mainPanel.add(drawPanel);
|
|
mainPanel.add(view);
|
|
mainPanel.add(steps);
|
|
mainPanel.add(config);
|
|
mainPanel.add(images);
|
|
|
|
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);
|
|
|
|
drawImg = new JPanel();
|
|
drawImg.setPreferredSize(new Dimension(this.imgHeight + 50,this.imgHeight + 10));
|
|
drawQImg = new JPanel();
|
|
drawQImg.setPreferredSize(new Dimension(this.imgHeight + 50,this.imgHeight + 10));
|
|
images.add(drawImg);
|
|
images.add(drawQImg);
|
|
|
|
frame.add(mainPanel);
|
|
drawPanel.add(glcanvas);
|
|
|
|
frame.pack();
|
|
frame.setVisible(true);
|
|
}
|
|
|
|
/**
|
|
* Button-Reaktivität
|
|
*
|
|
* @param e ActionEvent
|
|
*/
|
|
public void actionPerformed(ActionEvent e) {
|
|
/**
|
|
* Pfeilbuttons: Ändern der Ansicht
|
|
*/
|
|
if (e.getSource() == this.vr) this.rot = (this.rot + 345) % 360;
|
|
if (e.getSource() == this.vl) this.rot = (this.rot + 15) % 360;
|
|
if (e.getSource() == this.vu) this.azimut = (this.azimut + 345) % 360;
|
|
if (e.getSource() == this.vd) this.azimut = (this.azimut + 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());
|
|
this.img = Image.loadFile("./inputs/" + (String)this.s_input.getSelectedItem());
|
|
this.image = new ArrayList<>();
|
|
for (RGB p : this.orig) {
|
|
// kopiere die originalen Daten, damit die Liste später gemischt werden kann
|
|
this.image.add(p);
|
|
}
|
|
|
|
this.drawImage(this.img, this.drawImg);
|
|
} 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));
|
|
}
|
|
|
|
try {
|
|
BufferedImage i = Image.writeFile("./inputs/" + (String)this.s_input.getSelectedItem(), "", this.orig, this.quants);
|
|
this.drawImage(i, this.drawQImg);
|
|
} catch (Exception ex) {}
|
|
}
|
|
/**
|
|
* Epoche durchlaufen
|
|
*/
|
|
if (e.getSource() == this.b_epoc) {
|
|
Quant.doEpoch(this.image, this.quants);
|
|
|
|
try {
|
|
BufferedImage i = Image.writeFile("./inputs/" + (String)this.s_input.getSelectedItem(), "", this.orig, this.quants);
|
|
this.drawImage(i, this.drawQImg);
|
|
} catch (Exception ex) {}
|
|
}
|
|
/**
|
|
* Nicht bewegte Punkte versetzen
|
|
*/
|
|
if (e.getSource() == this.b_reset) {
|
|
Quant.resetQuants(this.quants);
|
|
|
|
try {
|
|
BufferedImage i = Image.writeFile("./inputs/" + (String)this.s_input.getSelectedItem(), "", this.orig, this.quants);
|
|
this.drawImage(i, this.drawQImg);
|
|
} catch (Exception ex) {}
|
|
}
|
|
/**
|
|
* 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.glcanvas.repaint();
|
|
}
|
|
|
|
private void drawImage(BufferedImage i, JPanel p) {
|
|
int w = i.getWidth();
|
|
int h = i.getHeight();
|
|
|
|
if (w > h) {
|
|
h = h * this.imgHeight / w;
|
|
w = this.imgHeight;
|
|
} else {
|
|
w = w * this.imgHeight / h;
|
|
h = this.imgHeight;
|
|
}
|
|
|
|
JLabel img = new JLabel(new ImageIcon(i.getScaledInstance(w,h,1)));
|
|
img.setPreferredSize(new Dimension(this.imgHeight, this.imgHeight));
|
|
p.removeAll();
|
|
p.add(img);
|
|
p.revalidate();
|
|
}
|
|
|
|
/**
|
|
* 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);
|
|
}
|
|
|
|
public static void main() throws Exception {
|
|
new OGL_Window();
|
|
}
|
|
} |