Mittels affiner Transformationen lassen sich einfache Bildmanipulationen vornehmen.
Die Application stellt ein JFrame mit zwei Darstellungsfenstern bereit, in denen ein Original- und ein affin transformiertes Bild dargestellt werden. Die Werte für die Transformationen
  • Skalieren
  • Rotieren
  • Transformieren
  • Scheren
können durch die Eingabe in Textfelder angepasst werden.
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JSlider;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;
import javax.swing.border.TitledBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class ImageDemo implements ChangeListener, ActionListener {

    private final String bildPfad = "img/test.jpg";

    private BufferedImage[] img;

    private JRadioButton scaleRB, rotateRB, transRB, scherRB;

    private JLabel origLabel, transLabel;

    private JTextField xScaleField, yScaleField,
            xPosRotateField, yPosRotateField, xTransField, yTransField,
            xScherField, yScherField;

    private JButton button;
    
    JSlider rotateSlider;

    private CardLayout cl;

    private JPanel cardPanel;

    private Box scalePanel, rotatePanel, transPanel, scherPanel;

    public ImageDemo() {
        initGUI();
    }
    
    private void initGUI() {
        JPanel rechtsPanel = initRB();

        img = getImages();

        if (img == null) {
            System.out.println("Image-Import fehlgeschlagen!");
            System.exit(1);
        }

        ImageIcon origIcon = new ImageIcon(img[0]);
        origLabel = new JLabel(origIcon);
        origLabel.setBorder(createBorder("Original"));

        ImageIcon transIcon = new ImageIcon();
        transLabel = new JLabel(transIcon);
        transLabel.setBorder(createBorder("Transformation"));

        JPanel centerPanel = new JPanel();
        centerPanel.setLayout(new GridLayout(2, 1));
        centerPanel.setBackground(Color.DARK_GRAY);
        centerPanel.add(origLabel);
        centerPanel.add(transLabel);

        JFrame frame = new JFrame("Affine Transformation");
        frame.add(centerPanel, BorderLayout.CENTER);
        frame.add(rechtsPanel, BorderLayout.EAST);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

    private Border createBorder(String title) {
        return new TitledBorder(new LineBorder(Color.WHITE), title,
                TitledBorder.ABOVE_BOTTOM, TitledBorder.LEADING, new Font(
                        "Verdana", Font.PLAIN, 12), Color.WHITE);
    }

    private JPanel initRB() {
        scaleRB = new JRadioButton("Skalierung", true);
        scaleRB.addChangeListener(this);
        rotateRB = new JRadioButton("Rotation");
        rotateRB.addChangeListener(this);
        transRB = new JRadioButton("Translation");
        transRB.addChangeListener(this);
        scherRB = new JRadioButton("Scherung");
        scherRB.addChangeListener(this);
        ButtonGroup buttonGroup = new ButtonGroup();
        buttonGroup.add(scaleRB);
        buttonGroup.add(rotateRB);
        buttonGroup.add(transRB);
        buttonGroup.add(scherRB);
        JPanel rBPanel = new JPanel(new GridLayout(4, 1, 0, 5));
        rBPanel.add(scaleRB);
        rBPanel.add(rotateRB);
        rBPanel.add(transRB);
        rBPanel.add(scherRB);

        JLabel xScaleLabel, yScaleLabel, faktorRotateLabel, xPosRotateLabel, yPosRotateLabel, xTransLabel, yTransLabel, xScherLabel, yScherLabel;
        xScaleLabel = new JLabel("X-Wert:");
        yScaleLabel = new JLabel("Y-Wert:");
        faktorRotateLabel = new JLabel("Winkel");
        xPosRotateLabel = new JLabel("X-Wert:");
        yPosRotateLabel = new JLabel("Y-Wert:");
        xTransLabel = new JLabel("X-Wert:");
        yTransLabel = new JLabel("Y-Wert:");
        xScherLabel = new JLabel("X-Wert:");
        yScherLabel = new JLabel("Y-Wert:");

        xScaleField = new JTextField(4);
        xScaleField.setPreferredSize(new Dimension(100, 20));
        yScaleField = new JTextField(4);
        yScaleField.setPreferredSize(new Dimension(100, 20));
        // Bereich 0 - 2*PI
        // wird im Listener durch 100 dividiert
        rotateSlider = new JSlider(0, 628, 0);
        rotateSlider.setMajorTickSpacing(150);
        rotateSlider.setPaintTicks(true);
        xPosRotateField = new JTextField(4);
        yPosRotateField = new JTextField(4);
        xTransField = new JTextField(4);
        yTransField = new JTextField(4);
        xScherField = new JTextField(4);
        yScherField = new JTextField(4);

        Dimension fillDim = new Dimension(10, Short.MAX_VALUE);

        scalePanel = new Box(BoxLayout.Y_AXIS);
        scalePanel.add(xScaleLabel);
        scalePanel.add(xScaleField);
        scalePanel.add(yScaleLabel);
        scalePanel.add(yScaleField);
        scalePanel.add(new Box.Filler(fillDim, fillDim, fillDim));

        rotatePanel = new Box(BoxLayout.Y_AXIS);
        rotatePanel.add(faktorRotateLabel);
        rotatePanel.add(rotateSlider);
        rotatePanel.add(xPosRotateLabel);
        rotatePanel.add(xPosRotateField);
        rotatePanel.add(yPosRotateLabel);
        rotatePanel.add(yPosRotateField);
        rotatePanel.add(new Box.Filler(fillDim, fillDim, fillDim));

        transPanel = new Box(BoxLayout.Y_AXIS);
        transPanel.add(xTransLabel);
        transPanel.add(xTransField);
        transPanel.add(yTransLabel);
        transPanel.add(yTransField);
        transPanel.add(new Box.Filler(fillDim, fillDim, fillDim));

        scherPanel = new Box(BoxLayout.Y_AXIS);
        scherPanel.add(xScherLabel);
        scherPanel.add(xScherField);
        scherPanel.add(yScherLabel);
        scherPanel.add(yScherField);
        scherPanel.add(new Box.Filler(fillDim, fillDim, fillDim));

        cl = new CardLayout(0, 20);
        cardPanel = new JPanel(cl);
        cardPanel.add(scalePanel, "Skalierung");
        cardPanel.add(rotatePanel, "Rotation");
        cardPanel.add(transPanel, "Translation (Verschieben)");
        cardPanel.add(scherPanel, "Scherung");

        button = new JButton("Transformieren");
        button.addActionListener(this);

        JPanel mainPanel = new JPanel(new BorderLayout(5, 10));
        mainPanel.add(rBPanel, BorderLayout.NORTH);
        mainPanel.add(cardPanel, BorderLayout.CENTER);
        mainPanel.add(button, BorderLayout.SOUTH);
        return mainPanel;
    }

    private BufferedImage[] scaleImage(String xStr, String yStr) {
        BufferedImage[] iArr = getImages();
        if (iArr == null)
            return null;

        // 1.0 ist Originalgroesse
        double x = str2double(xStr);
        double y = str2double(yStr);
        if(x == 0 || y == 0) return null;
        AffineTransform trans = AffineTransform.getScaleInstance(x, y);
        AffineTransformOp op = new AffineTransformOp(trans,
                AffineTransformOp.TYPE_BILINEAR);
        op.filter(iArr[0], iArr[1]);
        return iArr;
    }

    private BufferedImage[] rotateImage(String fStr, String xStr, String yStr) {
        BufferedImage[] iArr = getImages();
        if (iArr == null)
            return null;
        double x = str2double(xStr);
        double y = str2double(yStr);
        if(xStr.equals("-1")) x = iArr[0].getWidth()/2;
        if(yStr.equals("-1")) y = iArr[0].getHeight()/2;

        // um die Mitte rotieren
        // f = 6.284 - volle Drehung
        double f = str2double(fStr);
        AffineTransform trans = AffineTransform.getRotateInstance(f, x, y);
        AffineTransformOp op = new AffineTransformOp(trans,
                AffineTransformOp.TYPE_BILINEAR);
        op.filter(iArr[0], iArr[1]);
        return iArr;
    }

    private BufferedImage[] transImage(String xStr, String yStr) {
        BufferedImage[] iArr = getImages();
        if (iArr == null)
            return null;

        // Translation
        double x = str2double(xStr);
        double y = str2double(yStr);
        AffineTransform trans = AffineTransform.getTranslateInstance(x, y);
        AffineTransformOp op = new AffineTransformOp(trans,
                AffineTransformOp.TYPE_BILINEAR);
        op.filter(iArr[0], iArr[1]);
        return iArr;
    }

    private BufferedImage[] scherImage(String xStr, String yStr) {
        BufferedImage[] iArr = getImages();
        if (iArr == null)
            return null;

        // scheren
        double x = str2double(xStr);
        double y = str2double(yStr);
        AffineTransform trans = AffineTransform.getShearInstance(x, y);
        AffineTransformOp op = new AffineTransformOp(trans,
                AffineTransformOp.TYPE_BILINEAR);
        op.filter(iArr[0], iArr[1]);
        return iArr;
    }

    private BufferedImage[] getImages() {
        File file = new File(bildPfad);
        BufferedImage origImg = null;
        try {
            origImg = ImageIO.read(file);
        } catch (IOException ex) {
            System.err.println("Image-Datei kann nicht gelesen werden!");
            System.exit(1);
        }
        if (origImg != null) {
            BufferedImage destImg = new BufferedImage(origImg.getWidth(),
                    origImg.getHeight(), origImg.getType());
            BufferedImage[] i = { origImg, destImg };
            return i;
        }
        return null;
    }

    private void setImg(BufferedImage[] images) {
        if (images == null) {
            System.out.println("fehlgeschlaagen");
            return;
        }
        ImageIcon origIcon = new ImageIcon(images[0]);
        ImageIcon transIcon = new ImageIcon(images[1]);
        origLabel.setIcon(origIcon);
        transLabel.setIcon(transIcon);
    }

    private double str2double(String dStr) {
        if (dStr == null)
            return 1;
        dStr = dStr.replace(',', '.');
        try {
            return new Double(dStr).doubleValue();
        } catch (NumberFormatException nfe) {
            System.out.println("falsches Zahlformat");
        }
        return 0;
    }

    public void stateChanged(ChangeEvent e) {
        if (e.getSource() == scaleRB) {
            cl.show(cardPanel, "Skalierung");
        }
        if (e.getSource() == rotateRB) {
            cl.show(cardPanel, "Rotation");
        }
        if (e.getSource() == transRB) {
            cl.show(cardPanel, "Translation (Verschieben)");
        }
        if (e.getSource() == scherRB) {
            cl.show(cardPanel, "Scherung");
        }
    }

    public void actionPerformed(ActionEvent e) {
        if (scaleRB.isSelected()) {
            if(xScaleField.getText().equals("") || yScaleField.getText().equals("")) return;
            img = scaleImage(xScaleField.getText(), yScaleField.getText());
            setImg(img);
        }
        if (rotateRB.isSelected()) {
            String xFaktor = "-1", yFaktor = "-1";
            if(!xPosRotateField.getText().equals("") && !yPosRotateField.getText().equals("")){
                xFaktor = xPosRotateField.getText();
                yFaktor = yPosRotateField.getText();
            }
            double faktor = (double)rotateSlider.getValue()/100;
            img = rotateImage(new Double(faktor).toString(), xFaktor, yFaktor);
            setImg(img);
        }
        if (transRB.isSelected()) {
            if(xTransField.getText().equals("") || yTransField.getText().equals("")) return;
            img = transImage(xTransField.getText(), yTransField.getText());
            setImg(img);
        }
        if (scherRB.isSelected()) {
            if(xScherField.getText().equals("") || yScherField.getText().equals("")) return;
            img = scherImage(xScherField.getText(), yTransField.getText());
            setImg(img);
        }
    }

    public static void main(String args[]) {
        SwingUtilities.invokeLater(() -> new ImageDemo());
    }
}

Wenn Ihnen javabeginners.de gefällt, freue ich mich über eine Spende an diese gemeinnützigen Organisationen.

letzte Änderung an:
Streams


Javabeginners News-Feed News-Feed abonnieren