Werteüberprüfung und Bildmanipulation mit Hilfe der JAI-Bibliothek1
Die Klasse ermöglicht den Test einiger Einstellungsgrößen von Bildbearbeitungsmethoden der JAI-Bibliothek. Sie lässt sich problemlos um weitere Methoden erweitern.
Über Schieberegler können Werte zur Kontrast- und Helligkeitssteuerung, sowie zur Skalierung ausgelesen und in ihren Auswirkungen dargestellt werden.
Zur Erweiterung müssen lediglich in der Methode render() der erforderliche Parameterblock hinzugefügt und der Pfad zum Bild in Zeile 75 angepasst werden.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.image.RenderedImage;
import java.awt.image.renderable.ParameterBlock;
import java.io.File;
import java.io.IOException;

import javax.media.jai.JAI;
import javax.media.jai.RenderedOp;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JTextField;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import com.sun.media.jai.codec.FileSeekableStream;
import com.sun.media.jai.widget.DisplayJAI;

/*
 * file JAITest.java
 * @version 0.2
 * Created on 23.10.2006
 * Changed on 27.10.2006
 * @author Joerg Czeschla, yourwebs.de (c)2006
 * 
 * 
 * This file is free software; you can redistribute
 * it and/or modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the License,
 * or (at your option) any later version.
 * 
 * It is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * Galerist; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
 * Suite 330, Boston, MA 02111-1307, USA.
 */


public class JAITest extends JFrame implements ChangeListener, ActionListener, ItemListener {

    private static final long serialVersionUID = 1L;

    // GUI Elemente
    private JSlider slider1, slider2, slider3;

    private JTextField bildTF, methodeTF, param1TF, param2TF, param3TF;

    private JLabel bildLabel, methodeLabel;

    private JPanel hauptPanel, werteTFPanel, sliderPanel, slider1Panel, slider2Panel, slider3Panel, elementePanel,
            buttonPanel, bildPanel, boxPanel, obenPanel;

    private JButton okButt, cancelButt;

    private JComboBox comboBox = new JComboBox();

    private DisplayJAI displayJAI;

    private RenderedImage renderedImage = null;

    // Eingabeverzeichnisname
    private String inputFile = "verzeichnis/bild.jpg";

    // ComboBox-Starttext
    private String startText = "Bitte Methode w\u00E4hlen!";

    public JAITest() {

        // Slider
        slider1 = new JSlider(0, 0, 0);
        slider2 = new JSlider(0, 0, 0);
        slider3 = new JSlider(0, 0, 0);
        slider1.addChangeListener(this);
        slider2.addChangeListener(this);
        slider3.addChangeListener(this);

        // TextFelder
        bildTF = new JTextField(inputFile, 20);
        methodeTF = new JTextField("", 20);
        param1TF = new JTextField("0.00", 5);
        param1TF.addActionListener(this);
        param2TF = new JTextField("75.0", 5);
        param2TF.addActionListener(this);
        param3TF = new JTextField("0.00", 5);
        param3TF.addActionListener(this);

        // Label
        bildLabel = new JLabel("Bild: ");
        methodeLabel = new JLabel("Methode: ");

        // Buttons
        okButt = new JButton("ok");
        okButt.addActionListener(this);
        cancelButt = new JButton("cancel");
        cancelButt.addActionListener(this);

        // ComboBox
        comboBox = new JComboBox();
        comboBox.addItemListener(this);
        comboBox.addItem(startText);
        comboBox.addItem("threshold");
        comboBox.addItem("rescale");
        comboBox.addItem("addConst");
        comboBox.addItem("scale");

        // Panels
        hauptPanel = new JPanel(new BorderLayout());
        werteTFPanel = new JPanel();
        sliderPanel = new JPanel(new BorderLayout());
        slider1Panel = new JPanel(new FlowLayout());
        slider2Panel = new JPanel(new FlowLayout());
        slider3Panel = new JPanel(new FlowLayout());
        bildPanel = new JPanel(new FlowLayout());
        boxPanel = new JPanel(new FlowLayout());
        obenPanel = new JPanel(new BorderLayout());
        elementePanel = new JPanel(new BorderLayout());
        buttonPanel = new JPanel();

        // Bilddisplay
        displayJAI = new DisplayJAI();

        // Slider und Textfelder in Grundstellung setzen
        setAllDisplays(true);

        // Layoutmanagement (der Einfachheit halber ohne GridBagLayout)
        slider1Panel.add(slider1);
        slider1Panel.add(param1TF);
        slider2Panel.add(slider2);
        slider2Panel.add(param2TF);
        slider3Panel.add(slider3);
        slider3Panel.add(param3TF);

        sliderPanel.add(slider1Panel, BorderLayout.NORTH);
        sliderPanel.add(slider2Panel, BorderLayout.CENTER);
        sliderPanel.add(slider3Panel, BorderLayout.SOUTH);

        bildPanel.add(bildLabel);
        bildPanel.add(bildTF);
        boxPanel.add(methodeLabel);
        boxPanel.add(comboBox);
        boxPanel.add(methodeTF);
        obenPanel.add(bildPanel, BorderLayout.NORTH);
        obenPanel.add(boxPanel, BorderLayout.SOUTH);

        buttonPanel.add(okButt);
        buttonPanel.add(cancelButt);

        elementePanel.add(sliderPanel, BorderLayout.NORTH);
        elementePanel.add(werteTFPanel, BorderLayout.CENTER);
        elementePanel.add(buttonPanel, BorderLayout.SOUTH);

        hauptPanel.add(obenPanel, BorderLayout.NORTH);
        hauptPanel.add(elementePanel, BorderLayout.SOUTH);

        // Bild initialisieren
        if (verifyFile(bildTF.getText())) {
            RenderedImage ri = init();

            if (ri != null) {
                setzeBild(ri);
            }
        }

        hauptPanel.add(displayJAI, BorderLayout.CENTER);
        getContentPane().add(hauptPanel);
    } // Ende Konstruktor

    /**
     * Prüft die Pfadangabe und erzeugt einen InputStream des Bildes
     * 
     * @return FileSeekableStream des zu bearbeitenden Bildes
     */
    private RenderedImage init() {
        FileSeekableStream image = null;
        try {
            if (verifyFile(bildTF.getText())) {
                image = new FileSeekableStream(bildTF.getText());
                // RenderedImage erstellen
                renderedImage = JAI.create("stream", image);
                return renderedImage;
            }
        } catch (IOException e) {
            System.out.println("Bitte den Pfad zu einem Bild angeben!");
            setAllDisplays(true);
            return null;
        }
        return null;
    }

    /**
     * Prüft die Pfadangabe auf Existenz und Lesbarkeit
     */
    private boolean verifyFile(String pfad){
        File f = new File(pfad);
        if (f.isFile() && f.canRead()) {
            return true;
        }
        return false;
    }

    /**
     * positioniert das Bild auf dem Display
     * 
     * @param ri
     * @return
     */
    private void setzeBild(RenderedImage ri) {
        int breite = ri.getWidth(), hoehe = ri.getHeight();
        Dimension dim = new Dimension((800 - breite) / 2, (600 - hoehe) / 2);
        displayJAI.set(ri, (int) dim.getWidth(), (int) dim.getHeight());
    }

    /**
     * Factory-Methode zum methodenabhängigen Setzen der Slider
     * 
     * @param slider
     * @param visible
     *            sichtbar wenn true
     * @param min
     *            Minimalwert
     * @param max
     *            Maximalwert
     * @param val
     *            Ausgangsposition des Sliders
     */
    private void setSliderValue(JSlider slider, JTextField field, boolean visible, int min, int max, int val) {
        slider.setPreferredSize(new Dimension(300, 25));
        slider.setVisible(visible);
        slider.setMinimum(min);
        slider.setMaximum(max);
        slider.setValue(val);
        field.setVisible(visible);
        field.setText(new Double(val / 100).toString());
    }

    /**
     * Setzt alle Slider und Werte-Textfelder auf Grundstellung
     * 
     * @param visible
     */
    private void setAllDisplays(boolean visible) {
        setSliderValue(slider1, param1TF, visible, 0, 0, 0);
        setSliderValue(slider2, param2TF, visible, 0, 0, 0);
        setSliderValue(slider3, param3TF, visible, 0, 0, 0);
    }

    /**
     * Passt die Werte-Textfelder und Slider-Positionen aneinander an
     * 
     * @param ce
     */
    private void setTFText(ChangeEvent ce) {
        if (ce.getSource() == slider1) {
            param1TF.setText(new Double((double) slider1.getValue() / 100).toString());
        }
        if (ce.getSource() == slider2) {
            param2TF.setText(new Double((double) slider2.getValue() / 100).toString());
        }
        if (ce.getSource() == slider3) {
            param3TF.setText(new Double((double) slider3.getValue() / 100).toString());
        }
    }

    /**
     * Hauptmethode zur Bildbearbeitung
     * 
     * @param im
     *            Zu bearbeitendes RenderedImage
     * @param methode
     *            String der anzuwendenden Methode
     * @param wert1
     *            Wert1
     * @param wert2
     *            Wert2
     * @param wert3
     *            Wert3
     */
    private void render(RenderedImage im, String methode, String wert1, String wert2, String wert3) {
        if (renderedImage != null) {
            im = renderedImage;
            System.out.println("renderedImahe ungleich null!");
        }
        System.out.println(methode + " gew\u00E4hlt...");
        ParameterBlock pb = new ParameterBlock();
        pb.addSource(im);
        float f = 1.0F;
        double[] d1 = new double[3];
        double[] d2 = new double[3];
        double[] d3 = new double[3];

        if (methode.equals("") || methode.equals(startText)) {
            return;

        } else if (methode.equals("addConst")) {
            d1[0] = new Double(wert1).doubleValue();
            d1[1] = new Double(wert2).doubleValue();
            d1[2] = new Double(wert3).doubleValue();
            pb.add(d1);

        } else if (methode.equals("rescale")) {
            d1[0] = new Double(wert1).doubleValue();
            d1[1] = new Double(wert1).doubleValue();
            d1[2] = new Double(wert1).doubleValue();
            d2[0] = new Double(wert2).doubleValue();
            d2[1] = new Double(wert2).doubleValue();
            d2[2] = new Double(wert2).doubleValue();
            pb.add(d1);
            pb.add(d2);

        } else if (methode.equals("scale")) {
            f = new Float(wert1).floatValue();

            pb.add(f);
            pb.add(f);
            pb.add(0.0F);
            pb.add(0.0F);
            RenderedOp op = JAI.create(methode, pb);
            int breite = op.getWidth();
            int hoehe = op.getHeight();
            System.out.println("Breite: " + breite);
            System.out.println("Hoehe: " + hoehe);
            System.out.println("Berechnete Breite: " + (displayJAI.getWidth() - breite) / 2.0F);
            System.out.println("Berechnete Hoehe: " + (displayJAI.getHeight() - hoehe) / 2.0F);
            displayJAI.setOrigin((displayJAI.getWidth() - breite) / 2, 0);

        } else {
            d1[0] = new Double(wert1).doubleValue();
            d2[0] = new Double(wert2).doubleValue();
            d3[0] = new Double(wert3).doubleValue();
            if (d1[0] >= d2[0])
                d1[0] = d2[0];
            pb.add(d1);

            if (d2[0] <= d1[0])
                d2[0] = d1[0];
            pb.add(d2);

            pb.add(d3);
        }

        // Bild bearbeiten
        RenderedOp op = JAI.create(methode, pb);
        // bearbeitetes Bild registrieren
        renderedImage = op;
        // Bild darstellen
        displayJAI.set(op);
    }

    /**
     * Aufruf bei Methodenauswahl der Combobox
     */
    public void stateChanged(ChangeEvent ce) {

        setTFText(ce);

        RenderedImage ri = init();

        if (ri == null) {
            return;
        }

        render(ri, (String) comboBox.getSelectedItem(), param1TF.getText(), param2TF.getText(), param3TF.getText());
    }

    /**
     * aufgeruffen durch Textfelder und Buttons
     */
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == cancelButt) {
            System.exit(0);
        }
        if (e.getSource() == okButt) {
            RenderedImage ri = init();

            if (ri == null) {
                return;
            }
            String methode = (String) comboBox.getSelectedItem();

            render(ri, methode, param1TF.getText(), param2TF.getText(), param3TF.getText());
        }
        if (e.getSource() == param1TF) {
            slider1.setValue((int) (new Double(param1TF.getText()).doubleValue() * 100));
        }
        if (e.getSource() == param2TF) {
            slider2.setValue((int) (new Double(param2TF.getText()).doubleValue() * 100));
        }
        if (e.getSource() == param3TF) {
            slider3.setValue((int) (new Double(param3TF.getText()).doubleValue() * 100));
        }
    }

    /**
     * Sliderwerte je nach Auswahl einer Bearbeitungsmethode setzen und bei
     * Bewegung anpassen
     */
    public void itemStateChanged(ItemEvent e) {
        if (comboBox.getSelectedItem().equals(startText)) {
            setAllDisplays(true);
        }
        if (comboBox.getSelectedItem().equals("rescale")) {
            methodeTF.setText("Kontrast");
            setSliderValue(slider1, param1TF, true, 0, 400, 100);
            setSliderValue(slider2, param2TF, true, -25500, 25500, 0);
            setSliderValue(slider3, param3TF, false, 0, 0, 0);
        }
        if (comboBox.getSelectedItem().equals("threshold")) {
            methodeTF.setText("bin\u00E4rer Kontrast");
            setSliderValue(slider1, param1TF, true, 0, 500, 0);
            setSliderValue(slider2, param2TF, true, 5000, 10000, 7500);
            setSliderValue(slider3, param3TF, true, 0, 10000, 0);
        }
        if (comboBox.getSelectedItem().equals("addConst")) {
            methodeTF.setText("Helligkeit");
            setSliderValue(slider1, param1TF, true, -25000, 25000, 0);
            setSliderValue(slider2, param2TF, true, -25000, 25000, 0);
            setSliderValue(slider3, param3TF, true, -25000, 25000, 0);
        }
        if (comboBox.getSelectedItem().equals("scale")) {
            methodeTF.setText("Skalieren");
            setSliderValue(slider1, param1TF, true, 10, 190, 100);
            setSliderValue(slider2, param2TF, false, 0, 0, 0);
            setSliderValue(slider3, param3TF, false, 0, 0, 0);
        }
    }

    public static void main(String[] args) {
        JAITest jt = new JAITest();
        jt.setSize(800, 800);
        jt.setTitle("JAI-Test");
        jt.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jt.setVisible(true);
    }
}
Zur weiteren Vertiefung der JAI-Thematik sei auf die Docs unter

http://docs.oracle.com/cd/E19957-01/806-5413-10/806-5413-10.pdf


verwiesen. Man beachte jedoch, dass diese nicht mehr so ganz aktuell sind. Insbesondere wird auf einige, mittlerweile als deprecated eingestufte Elemente wie etwa ScrollingImagePanel verwiesen. Dies sollte unbedingt durch die Klasse DisplayJAI ersetzt werden.
1)Um die JAI-Bibliothek nutzen zu können, muss diese separat installieren werden.
letzte Änderung an:
Tabelle erstellen


Javabeginners News-Feed News-Feed abonnieren