Ein Bild drehen in Java - Höhe/Breite verkehrt



  • Ich versuchte mich mal etwas in Java und habe nun ein Problem; ich möchte ein Bild drehen (Image-Klasse), dazu muss ich es erst in ein BufferedImage kopieren (anscheinend). Habe ienen Ausschnitt gefunden zum drehen und nun passiert folgendes:
    Das Bild wird gedreht aber das Image/BufferedImage-Objekt behält seie Höhe/Breite, so dass einen Teil des Bildes abgeschnitten wird und schwarze Ränder entstehen. Ich habe beim Anlegen des BufferedImage-Objekts, in welches die Funktion

    private static BufferedImage rotateImage(BufferedImage src, double degrees)
    

    das gedrehte Bild zurückgibt aber absichtlich die Höhe/Breite vertauscht! Versuchte es natürlich auch umgekehrt aber immer mit dem Ergebnis.
    Hier etwas mehr Code:

    if(Label.equals("drehen")){
        	  turnImage();
        	  m_bildanzeige.repaint();
          }
    
    ....
    
    public void turnImage() {
    
    	  BufferedImage outImg = new BufferedImage(m_aktBild.getWidth(m_bildanzeige), m_aktBild.getHeight(m_bildanzeige), BufferedImage.TYPE_INT_RGB);
    		Graphics g = outImg.getGraphics();
    		g.drawImage(m_aktBild, 0, 0, null);
    		g.dispose();
    		BufferedImage turnedImg = new BufferedImage(m_aktBild.getHeight(m_bildanzeige), m_aktBild.getWidth(m_bildanzeige), BufferedImage.TYPE_INT_RGB);
    		 turnedImg=rotateImage(outImg, 90);
    		 /*Graphics g2=m_aktBild.getGraphics();
    		 g2.drawImage(turnedImg, 0, 0, null);
    		 g2.dispose();*/
    		 m_aktBild=turnedImg;
    		 m_tempAnzeigeBild=m_aktBild;
      }
    
      private static BufferedImage rotateImage(BufferedImage src, double degrees) {
          AffineTransform affineTransform = AffineTransform.getRotateInstance(
                  Math.toRadians(degrees),
                  src.getWidth() / 2,
                  src.getHeight() / 2);
          BufferedImage rotatedImage = new BufferedImage(src.getWidth(), src
                  .getHeight(), src.getType());
          Graphics2D g = (Graphics2D) rotatedImage.getGraphics();
          g.setTransform(affineTransform);
          g.drawImage(src, 0, 0, null);
          return rotatedImage;
      }
    

    und das ganze Projekt:

    import java.awt.*;
    
    import javax.imageio.ImageIO;
    import javax.swing.*;
    
    import sun.java2d.loops.ScaledBlit;
    import java.awt.print.*;
    import javax.print.attribute.*;
    import java.awt.event.*;
    import java.awt.image.BufferedImage;
    import java.io.*;
    import java.awt.geom.AffineTransform;
    
    public class JBildbearbeitung extends JFrame {
      static JBildbearbeitung m_fenster;
      String m_dateiname;             // Name der Datei
      Image   m_aktBild;              // Referenz auf das aktuelle Bild
      Image m_tempAnzeigeBild;
      CBildLeinwand m_bildanzeige;    // JPanel zum Anzeigen des Bildes
      int m_Xpos,m_Ypos;              // neue Position, an der die 
                                      // linke obere Ecke des Bildes 
                                      // angezeigt wird
      int m_bild_x1,m_bild_y1;        // die aktuelle Begrenzung 
      int m_bild_x2,m_bild_y2;        // des Bildes
      int m_bildHoehe,m_bildBreite;   // Höhe und Breite in Pixeln
    
      String fileformat="jpg";
    
      JPanel panel;
      JTextField m_width; 
      JTextField m_height;
      JButton bresize;
      JButton bresize2;
      JButton bturn;
      JLabel heightlabel;
      JLabel widthlabel;
      // Ereignisbehandlung
      class CMeinActionLauscher implements ActionListener {
        public void actionPerformed(ActionEvent e) {
          String Label;
    
          Label = e.getActionCommand();
    
          if(Label.equals("Programm beenden"))
             System.exit(0);
    
          if(Label.equals("Bild laden"))
             bildLaden();     
    
          if (Label.equals("einzoomen")) {
        	  m_tempAnzeigeBild=m_aktBild.getScaledInstance((m_tempAnzeigeBild.getWidth(m_bildanzeige)*2), (m_tempAnzeigeBild.getHeight(m_bildanzeige)*2), Image.SCALE_FAST);
        	  m_bildanzeige.repaint();
          }
          if (Label.equals("auszoomen")) {
        	  m_tempAnzeigeBild=m_aktBild.getScaledInstance((m_tempAnzeigeBild.getWidth(m_bildanzeige)/2), (m_tempAnzeigeBild.getHeight(m_bildanzeige)/2), Image.SCALE_FAST);
        	  m_bildanzeige.repaint();
          }
          if (Label.equals("+"))
          { 
        	  int breite=Integer.parseInt(m_width.getText());
        	  int hoehe=Integer.parseInt(m_height.getText());
        	  breite=breite*2; hoehe=hoehe*2;
        	  m_width.setText(String.valueOf(breite));
        	  m_height.setText(String.valueOf(hoehe));
        	  ResizeImage(breite, hoehe);
        	  m_bildanzeige.repaint();
          }
          if(Label.equals("-")) {
    
        	  int breite=Integer.parseInt(m_width.getText());
        	  int hoehe=Integer.parseInt(m_height.getText());
        	  breite=breite/2; hoehe=hoehe/2;
        	  m_width.setText(String.valueOf(breite));
        	  m_height.setText(String.valueOf(hoehe));
        	  ResizeImage(breite, hoehe);
        	  m_bildanzeige.repaint();
    
          }
          if(Label.equals("drehen")){
        	  turnImage();
        	  m_bildanzeige.repaint();
          }
    
          if(Label.equals("info...")) {
        	  JOptionPane.showMessageDialog(null, "JBildbearbeitung (c) 2009, C. M. Obrecht; Reben Studio, Aufnahmemedien +Informatik.\nhttp://homepage.hispeed.ch/reben \n \nÖffnet Bilder in den Formaten gif, jpg und png \n(eventuell abhängig von Ihrem Betriebssystem) und speichert in jpg und png. \n\nWird ein Bildformat nicht unterstützt welches Sie zu öffnen versuchten wird in der Grössenanzeige -1 angezeigt.\n\nDateiendungen müssen beim Öffnen/Speichern NICHT mit angegeben werden.", "Info über...", JOptionPane.OK_CANCEL_OPTION);
          }
          if(Label.equals("Bild speichern (JPEG .jpg)")){
        	  saveImage(m_aktBild);
          }
          if (Label.equals("Bild drucken")){
        	  printImage();
          }
          if (Label.equals("Bild speichern (PNG .png)")) {
        	  SaveImgAsPng(m_aktBild);
          }
        }
        }
    
      // Im Konstruktor werden ein Panel (als Zeichenfläche)
      // und eine Menüleiste angelegt
      JBildbearbeitung(String titel) {
        super(titel);
    
        m_Xpos = m_Ypos = 0;       // Startposition : links oben
        m_bild_x1 = m_bild_x2 = m_bild_y1 = m_bild_y2 = 0;
    
        // Zu Beginn ist kein Bild geladen
        m_dateiname = null;
        m_aktBild = null;
    
        // Einen Layout-Manager anlegen
        setLayout(new FlowLayout());
    
        panel=new JPanel(); 
        widthlabel=new JLabel("Breite:");
        m_width=new JTextField(4);
    
        heightlabel=new JLabel("Höhe:");
        m_height=new JTextField(4);
        bresize=new JButton("+");
        bresize2=new JButton("-");
        bturn=new JButton("drehen");
        panel.add(bresize2);
        panel.add(widthlabel);
        panel.add(m_width);
        panel.add(heightlabel);
        panel.add(m_height);
        panel.add(bresize);
        panel.add(bturn);
        bresize.addActionListener(new CMeinActionLauscher());
        bresize2.addActionListener(new CMeinActionLauscher());
        bturn.addActionListener(new CMeinActionLauscher());
        add(panel);
    
        // Eine Leinwand anlegen (von JPanel abgeleitet)
        m_bildanzeige  = new CBildLeinwand();
        add(m_bildanzeige);
    
        // Das Fenster mit einer Menüleiste versehen
        JMenuBar menueleiste = new JMenuBar();
        setJMenuBar(menueleiste);
    
        // Die PopupMenüs der Menüleiste erstellen
        JMenu menu1 = new JMenu("Datei");
        JMenu menu2= new JMenu("Zoom");
        JMenu menu3=new JMenu("Info");
    
        JMenuItem item1  = new JMenuItem("Bild laden");
        JMenuItem item3=new JMenuItem("Bild speichern (JPEG .jpg)");
        JMenuItem itemPNG=new JMenuItem("Bild speichern (PNG .png)");
        JMenuItem item4=new JMenuItem("Bild drucken");
        JMenuItem zoomitem1=new JMenuItem("einzoomen");
        JMenuItem zoomitem2=new JMenuItem("auszoomen");
        JMenuItem infoitem=new JMenuItem("info...");
        item1.addActionListener(new CMeinActionLauscher());
    zoomitem1.addActionListener(new CMeinActionLauscher());
    zoomitem2.addActionListener(new CMeinActionLauscher());
    item3.addActionListener(new CMeinActionLauscher());
    item4.addActionListener(new CMeinActionLauscher());
    itemPNG.addActionListener(new CMeinActionLauscher());
        JMenuItem item2 = new JMenuItem("Programm beenden");
        item2.addActionListener(new CMeinActionLauscher());
        infoitem.addActionListener(new CMeinActionLauscher());
        menu1.add(item1);
        menu1.add(item3);
        menu1.add(itemPNG);
        menu1.add(item4);
        menu1.add(item2);
        menu2.add(zoomitem1);
        menu2.add(zoomitem2);
        menu3.add(infoitem);
        menueleiste.add(menu1);
        menueleiste.add(menu2);
        menueleiste.add(menu3);
    
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
      }
      public void ResizeImage(int width, int height){
    	  m_tempAnzeigeBild=m_aktBild.getScaledInstance(width, height, Image.SCALE_SMOOTH);
    	  m_aktBild=m_tempAnzeigeBild;
      }
      public void saveImage(Image Bild) {
    	  FileDialog d = new FileDialog(this,"Bilddatei speichern...",
                  FileDialog.SAVE);
    
    	  d.setVisible(true);
    	  if(d.getFile() == null)
    		  return;
    	  String filename;
    	  if (!d.getFile().endsWith(".jpg")){
    filename = d.getDirectory()+"/"+ d.getFile()+".jpg";
    fileformat="jpg";
    	  }
    
    	  else {
    		  filename = d.getDirectory()+"/"+ d.getFile();
    		  fileformat="jpg";
    	  }
    
    // Falls der Benutzer keine Datei ausgewählt hat, wird null
    // zurückgegeben
    // Dann nichts weiter tun
    
    	  if (Bild!=null) {
    		  try{ File f=new File(filename);
    
    		  BufferedImage outImg = new BufferedImage(Bild.getWidth(m_bildanzeige), Bild.getHeight(m_bildanzeige), BufferedImage.TYPE_INT_RGB);
    			Graphics g = outImg.getGraphics();
    			g.drawImage(Bild, 0, 0, null);
    			g.dispose();
    
    			ImageIO.write(outImg, fileformat, f);
    
    		  }
    		  catch(IOException e) {JOptionPane.showMessageDialog(null, "Fehler! "+e.getMessage(), "Fehler beim Speichern!", JOptionPane.OK_CANCEL_OPTION); }
    	  }
      }
    
      public void SaveImgAsPng(Image Bild){
    
    	  FileDialog d = new FileDialog(this,"Bilddatei speichern...",
                  FileDialog.SAVE);
    
    	  d.setVisible(true);
    	  if(d.getFile() == null)
    		  return;
    	  String filename;
    	  if (!d.getFile().endsWith(".png")){
    filename = d.getDirectory()+"/"+ d.getFile()+".png";
    fileformat="png";
    	  }
    
    	  else {
    		  filename = d.getDirectory()+"/"+ d.getFile();
    		  fileformat="png";
    	  }
    
    // Falls der Benutzer keine Datei ausgewählt hat, wird null
    // zurückgegeben
    // Dann nichts weiter tun
    
    	  if (Bild!=null) {
    		  try{ File f=new File(filename);
    
    		  BufferedImage outImg = new BufferedImage(Bild.getWidth(m_bildanzeige), Bild.getHeight(m_bildanzeige), BufferedImage.TYPE_INT_RGB);
    			Graphics g = outImg.getGraphics();
    			g.drawImage(Bild, 0, 0, null);
    			g.dispose();
    
    			ImageIO.write(outImg, fileformat, f);
    
    		  }
    		  catch(IOException e) { JOptionPane.showMessageDialog(null, "Fehler! "+e.getMessage(), "Fehler beim Speichern!", JOptionPane.OK_CANCEL_OPTION);}
    	  }
      }
      public void turnImage() {
    
    	  BufferedImage outImg = new BufferedImage(m_aktBild.getWidth(m_bildanzeige), m_aktBild.getHeight(m_bildanzeige), BufferedImage.TYPE_INT_RGB);
    		Graphics g = outImg.getGraphics();
    		g.drawImage(m_aktBild, 0, 0, null);
    		g.dispose();
    		BufferedImage turnedImg = new BufferedImage(m_aktBild.getHeight(m_bildanzeige), m_aktBild.getWidth(m_bildanzeige), BufferedImage.TYPE_INT_RGB);
    		 turnedImg=rotateImage(outImg, 90);
    		 /*Graphics g2=m_aktBild.getGraphics();
    		 g2.drawImage(turnedImg, 0, 0, null);
    		 g2.dispose();*/
    		 m_aktBild=turnedImg;
    		 m_tempAnzeigeBild=m_aktBild;
      }
    
      private static BufferedImage rotateImage(BufferedImage src, double degrees) {
          AffineTransform affineTransform = AffineTransform.getRotateInstance(
                  Math.toRadians(degrees),
                  src.getWidth() / 2,
                  src.getHeight() / 2);
          BufferedImage rotatedImage = new BufferedImage(src.getWidth(), src
                  .getHeight(), src.getType());
          Graphics2D g = (Graphics2D) rotatedImage.getGraphics();
          g.setTransform(affineTransform);
          g.drawImage(src, 0, 0, null);
          return rotatedImage;
      }
    
      public void printImage(){
    	  PrintDialogExample pe=new PrintDialogExample();
    	  pe.SetImage(m_aktBild);
    	  PrinterJob job = PrinterJob.getPrinterJob();
          PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
          PageFormat pf = job.pageDialog(aset);
          job.setPrintable(pe, pf);
    
          boolean ok = job.printDialog(aset);
          if (ok) {
              try {
                   job.print(aset);
              } catch (PrinterException ex) {JOptionPane.showMessageDialog(null, "Fehler! "+ex.getMessage(), "Fehler beim Drucken!", JOptionPane.OK_CANCEL_OPTION);}
          }
      }
      // Eine Bilddatei laden
      public void bildLaden(){
        FileDialog d = new FileDialog(this,"Bilddatei laden...",
                                      FileDialog.LOAD);
    
        d.setVisible(true);
        m_dateiname = d.getDirectory()+"/"+ d.getFile();
    
        // Falls der Benutzer keine Datei ausgewählt hat, wird null
        // zurückgegeben
        // Dann nichts weiter tun
        if(m_dateiname == null)
           return;
    
        // Bild laden 
        ImageIcon tmp = new ImageIcon(m_dateiname);
        m_aktBild = tmp.getImage(); 
        m_tempAnzeigeBild=m_aktBild;
    
        // Die Begrenzungskoordinaten des Bildes ermitteln
        m_bildBreite = m_tempAnzeigeBild.getWidth(m_bildanzeige);
        m_bildHoehe = m_tempAnzeigeBild.getHeight(m_bildanzeige);
    
        m_width.setText(Integer.toString(m_bildBreite)); m_height.setText(Integer.toString(m_bildHoehe));
        m_bild_x1 = m_Xpos;
        m_bild_y1 = m_Ypos;
        m_bild_x2 = m_bild_x1 + m_bildBreite;
        m_bild_y2 = m_bild_y1 + m_bildHoehe;
    m_fenster.setTitle(m_fenster.getTitle()+" - "+d.getFile());
        m_bildanzeige.repaint();
      }
    
      public static void main(String[] args) {
        m_fenster = new JBildbearbeitung("JBildbearbeitung");
        m_fenster.setSize(600,400);
        m_fenster.pack();
        m_fenster.setVisible(true);
      }
    
      // Diese Klasse dient zum Anzeigen und Manipulieren des Bildes
      class CBildLeinwand extends JPanel {
        // Panel neu zeichnen
        public void paintComponent(Graphics g) {
          super.paintComponent(g);
    
          // Falls ein Bild geladen ist, das Bild anzeigen
          if(m_tempAnzeigeBild != null)
            g.drawImage(m_tempAnzeigeBild,m_Xpos,m_Ypos,this);
        }
    
        public Dimension getMinimumSize() {
          return m_fenster.getSize();
        }
        public Dimension getPreferredSize() {
          return getMinimumSize();
        }
      }
    }
    

Anmelden zum Antworten