v1.1 README
							parent
							
								
									1a0376ec61
								
							
						
					
					
						commit
						55d404c60d
					
				|  | @ -79,6 +79,12 @@ public class OGL_Window implements GLEventListener, KeyListener, ActionListener | |||
|         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); | ||||
|          | ||||
|  | @ -124,12 +130,6 @@ public class OGL_Window implements GLEventListener, KeyListener, ActionListener | |||
|             ); | ||||
|         } | ||||
|         gl.glEnd(); | ||||
|          | ||||
|         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(); | ||||
|     } | ||||
|      | ||||
|     @Override | ||||
|  |  | |||
							
								
								
									
										16
									
								
								README.TXT
								
								
								
								
							
							
						
						
									
										16
									
								
								README.TXT
								
								
								
								
							|  | @ -7,14 +7,22 @@ PROJEKTZWECK: Liest ein Bild aus einer JPG-Datei ein und stellt die | |||
| VERSION oder DATUM: 1.1 (27.10.2023) | ||||
| WIE IST DAS PROJEKT ZU STARTEN: OGL_Window -> main()-Methode starten | ||||
| AUTOR: Alexander Kimmig (a.kimmig@dhg-rw.de) | ||||
| BENUTZERHINWEISE: Die ChartDirector_s.jar muss in den BlueJ-Einstellungen | ||||
| BENUTZERHINWEISE: Die OpenGL-Bibliotheken müssen von | ||||
|         https://jogamp.org/wiki/index.php/Downloading_and_installing_JOGL | ||||
|     bzw. Direktlink: | ||||
|         https://jogamp.org/deployment/jogamp-current/archive/jogamp-all-platforms.7z | ||||
|     heruntergeladen und in den BlueJ-Einstellungen | ||||
|     als externe Benutzerbibliothek eingebunden werden. | ||||
|     (Quelle: https://www.advsofteng.com/doc/cdjava.htm) | ||||
| 
 | ||||
| BEKANNTE BUGS: | ||||
|     * Achsen werden immer hinter der Punktwolke gezeichnet | ||||
| 
 | ||||
| CHANGELOG: | ||||
| * Version 1.1 (27.10.2023) | ||||
|     * umgestellt auf OpenGL, manuelles Rendering | ||||
|     *  | ||||
|     * umgestellt auf OpenGL, manuelles Rendering, dadurch deutlich bessere Performance | ||||
|     * Bild wird original und live-quantisiert | ||||
|     * Punktwolke wird farbig dargestellt | ||||
|     * nach einem Klick auf das Diagramm kann dieses auch mit den Pfeiltasten gedreht werden | ||||
| * Version 1.0.1 (26.10.2023) | ||||
|     * Möglichkeit, das Fenster in kleinerer Auflösung anzuzeigen | ||||
|     * Möglichkeit, die Punktwolke farbig anzuzeigen | ||||
|  |  | |||
							
								
								
									
										276
									
								
								Window.java
								
								
								
								
							
							
						
						
									
										276
									
								
								Window.java
								
								
								
								
							|  | @ -1,276 +0,0 @@ | |||
| /** | ||||
|  * BITTE NICHT MEHR NUTZEN -> stattdessen OGL_Window verwenden! | ||||
|  */ | ||||
| 
 | ||||
| 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.1 | ||||
|  */ | ||||
| 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 int size; | ||||
|     private boolean colorize; | ||||
|      | ||||
|     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(int size, boolean colorize) | ||||
|     { | ||||
|         this.size = size; | ||||
|         this.colorize = colorize; | ||||
|          | ||||
|         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(size, size)); | ||||
|         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(this.size, this.size); | ||||
|         c.setPlotRegion((int)(this.size / 2), (int)(this.size * 0.48), (int)(this.size * 0.6), (int)(this.size * 0.6), (int)(this.size * 0.45)); | ||||
|         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); | ||||
|          | ||||
|         double[] x, y, z; | ||||
|         // Bildpunkte
 | ||||
|         if (colorize) { | ||||
|             x = new double[1]; | ||||
|             y = new double[1]; | ||||
|             z = new double[1]; | ||||
|             for (RGB p : image) { | ||||
|                 x[0] = p.r; | ||||
|                 y[0] = p.g; | ||||
|                 z[0] = p.b; | ||||
|                 //               Koordinaten    Form        Größe  Farbe ARGB    Rahmen ARGB
 | ||||
|                 c.addScatterGroup(x,y,z, "", Chart.CircleShape, 5, p.toInt(224), 0xFF000000); | ||||
|             } | ||||
|         } else { | ||||
|             x = new double[image.size()]; | ||||
|             y = new double[image.size()]; | ||||
|             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()); | ||||
|                 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); | ||||
|                 } | ||||
|             } 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(); | ||||
|     } | ||||
| } | ||||
		Loading…
	
		Reference in New Issue