Rückgabewert von JSlider

innoc

Aktives Mitglied
Hallo liebes Forum,

ich habe zum Skalieren eines JPG-Bilds eine abstrakte Klasse JPanel zusammen mit einem JSlider wie folgt implementiert:

Java:
         final JPanel p = new JPanel() {
            protected void paintComponent(Graphics g) {

             Dimension panelSize = getSize();
             int panelWidth = panelSize.width;
             int panelHeight = panelSize.height;

             // Clear background and paint the image
             g.setColor(Color.WHITE);
             g.fillRect(0, 0, template.getWidth(null), template.getHeight(null));

             int sliderWidth = (int) (bufferedImage.getWidth(null) * scaleFactor)/100;
             int sliderHeight = (int) (bufferedImage.getHeight(null) * scaleFactor)/100;

             int imageX = panelWidth/2 - sliderWidth/2;
             int imageY = panelHeight/2 - sliderHeight/2;

 
             g.drawImage(template, imageX, imageY, sliderWidth, sliderHeight, null);
             Image image = new ImageIcon(template.getScaledInstance(sliderWidth, sliderHeight, Image.SCALE_SMOOTH)).getImage();
 
             textLabel.setText(Integer.toString(scaleFactor) + ": " + Integer.toString(image.getWidth(null)) + " x " + Integer.toString(image.getHeight(null)));
             this.add(textLabel);
            }
          };

          final JSlider slider = new JSlider(0, 200);
          slider.addChangeListener(new ChangeListener() {
            public final void stateChanged(ChangeEvent e) {
              scaleFactor = slider.getValue();
              p.repaint();
            }
          });


          JPanel panel = new JPanel();
          panel.add(slider);
          textLabel = new JLabel(Integer.toString(template.getWidth(null)) + " x " + Integer.toString(template.getHeight(null)));


          getContentPane().add(p, BorderLayout.CENTER);
          getContentPane().add(panel, BorderLayout.SOUTH);
          setVisible(true);

Die durch den JSlider veränderten Werte für die Bildhöhe und Bildweite lasse ich mir in einem Textfeld ausgeben. Ich möchte nun außerhalb der abstrakten Klasse das mit dem JSlider neu skalierte Originalbild als Kopie abspeichern. Ich könnte dafür natürlich die Werte für die Höhe und Breite aus dem Textfeld auslesen und als Parameter für getScaledInstance() verwenden. Hier nun meine Frage: Gibt es nicht eine bessere Methode, ohne den Umweg über ein Textfeld, um auf die durch den JSlider veränderten Werte für die Bildhöhe und -breite außerhalb der abstrakten Klasse zugreifen zu können?
 
A

a0027301

Gast
Schaffe entsprechende Getter, die dir die Bilddaten zurückgeben.

Bsp.

public Dimension getBildgroesse()
{
return new Dimension(imageX,imageY);
}
 

innoc

Aktives Mitglied
Hallo a0027301,

ich habe Dimension nun in das Programm wie folgt eingebaut:
Java:
          final JPanel p = new JPanel() {
            protected void paintComponent(Graphics g) {

             Dimension panelSize = getSize();
             int panelWidth = panelSize.width;
             int panelHeight = panelSize.height;

             // Clear background and paint the image
             g.setColor(Color.WHITE);
             g.fillRect(0, 0, template.getWidth(null), template.getHeight(null));

             int sliderWidth = (int) (bufferedImage.getWidth(null) * scaleFactor)/100;
             int sliderHeight = (int) (bufferedImage.getHeight(null) * scaleFactor)/100;

             imageX = panelWidth/2 - sliderWidth/2;
             imageY = panelHeight/2 - sliderHeight/2;


             g.drawImage(template, imageX, imageY, sliderWidth, sliderHeight, null);
             Image image = new ImageIcon(template.getScaledInstance(sliderWidth, sliderHeight, Image.SCALE_SMOOTH)).getImage();
             textLabel.setText(Integer.toString(scaleFactor) + ": " + Integer.toString(d.getWidth()) + " x " + Integer.toString(d.getHeight()));
             this.add(textLabel);
            }

            public Dimension getImageSize() {
              return new Dimension(imageX, imageY);
            }

          };

          final JSlider slider = new JSlider(0, 200);
          slider.addChangeListener(new ChangeListener() {
            public final void stateChanged(ChangeEvent e) {
              scaleFactor = slider.getValue();
              p.repaint();
            }
          });



          JPanel panel = new JPanel();
          panel.add(slider);
          textLabel = new JLabel(Integer.toString(d.getWidth()) + " x " + Integer.toString(d.getHeight()));

          getContentPane().add(p, BorderLayout.CENTER);
          getContentPane().add(panel, BorderLayout.SOUTH);
          setVisible(true);

Die Ausgabe im Textfeld zeigt mir nur die ursprüngliche Höhe und Breite des Bildes an. Die durch JSlider geänderten Werte für die Bildhöhe und Bildbreite werden jedoch nicht in Dimension übernommen. Brauch ich dazu nicht einen Listener?

Vielen Dank für die Hilfe.
 
Zuletzt bearbeitet:
S

SlaterB

Gast
dein Programm ist bisschen voll und doch fehlt ne Menge, was ist template, was ist bufferedImage?
wenn alles da ist und ich nur ein kleines jpeg hinzufügen muss, kann ich es versuchen, einen Fehler zu finden,

hier solange aus Interesse eine vereinfachte Variante, die nur ein schwarzes Rechteck malt, das funktioniert auch:
Java:
public class TestGUI  extends JFrame {
    int scaleFactor = 50;

    public TestGUI() {
        final JPanel p = new JPanel()    {
                protected void paintComponent(Graphics g)  {
                    super.paintComponent(g); // besser immer verwenden, löscht den Inhalt
                    Dimension panelSize = getSize();
                    int panelWidth = panelSize.width;
                    int panelHeight = panelSize.height;

                    int sliderWidth = 400 * scaleFactor / 100;
                    int sliderHeight = 300 * scaleFactor / 100;

                    int imageX = panelWidth / 2 - sliderWidth / 2;
                    int imageY = panelHeight / 2 - sliderHeight / 2;
                    g.fillRect(imageX, imageY, sliderWidth, sliderHeight);
                }
            };

        final JSlider slider = new JSlider(0, 100);
        slider.addChangeListener(new ChangeListener()   {
                public final void stateChanged(ChangeEvent e)  {
                    scaleFactor = slider.getValue();
                    p.repaint();
                }
            });

        add(p, BorderLayout.CENTER);
        add(slider, BorderLayout.SOUTH);
        setSize(300, 300);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    }

    public static void main(String[] args)
    {
        new TestGUI();
    }
}
 

innoc

Aktives Mitglied
Hallo SlaterB,

unten ist der gesamte Teil des Programms. Ich will das Bild nach dem Skalieren mit dem JSlider über einen JMenuBar-Eintrag "Save" abspeichern. Vielleicht ist der Programmcode etwas umständlich, da ich ihn nach dem Try-and-Error-Prinzip im weiter verändert habe. Immerhin kann ich das Bild über die GUI aufrufen und mit dem Slider skalieren, nur das skalierte Bild abspeichern will noch nicht funktionieren. Meine bisherigen Versuche endeten bisher meist mit dem Abspeichern eines schwarzen Rahmens. Daher meine Idee einfach nur die Höhe und Breite vom Slider zu übernehmen und das Originalbild über getScaledInstance() zu ändern. Vielleicht hat ja jemand eine bessere Idee.

Java:
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import javax.imageio.*;
import javax.imageio.stream.*;
import javax.swing.*;
import javax.swing.filechooser.FileFilter;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;


public class ImageViewerGUI extends BaseFrame {
  JFileChooser d;
  BufferedImage bufferedImage;
  JPanel p;
  JLabel textLabel;
  Image i; 
  int scaleFactor = 100;
  int currentWidth;
  int imageX = 0;
  int imageY = 0;


  public ImageViewerGUI() {

    // create a file chooser
    d = new JFileChooser();
    d.setFileFilter(new FileFilter() {
      public boolean accept(File f) {
        return f.isDirectory() || f.getName().toLowerCase().endsWith(".jpg");
      }
      public String getDescription() {
        return "*.jpg";
      }
    });
    
    // Create menu bar
    JMenuBar mbar = new JMenuBar();
    setJMenuBar(mbar);

    // Build the File-Menu
    JMenu menu = new JMenu("File");
    menu.setMnemonic(KeyEvent.VK_F);
    mbar.add(menu);

    // The Open JMenuItem
    JMenuItem openItem = new JMenuItem("Open", KeyEvent.VK_O);
    openItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, InputEvent.CTRL_MASK));
    openItem.getAccessibleContext().setAccessibleDescription("Open a new image file");
    openItem.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {

        int status = d.showOpenDialog(null);
        if (status == d.APPROVE_OPTION) {
          File file = d.getSelectedFile();
          final Image template = new ImageIcon(Toolkit.getDefaultToolkit().getImage(file.getAbsolutePath())).getImage();

          // Create the buffered image
          // notice: bufferedImage is a bufferedImage type
          bufferedImage = new BufferedImage(template.getWidth(null), template.getHeight(null), BufferedImage.TYPE_INT_RGB);


          // Copy image to buffered image
          Graphics g = bufferedImage.getGraphics();

          final JPanel p = new JPanel() {
            protected void paintComponent(Graphics g) {

             Dimension panelSize = getSize();
             int panelWidth = panelSize.width;
             int panelHeight = panelSize.height;

             // Clear background and paint the image
             g.setColor(Color.WHITE);
             g.fillRect(0, 0, template.getWidth(null), template.getHeight(null));

             int sliderWidth = (int) (bufferedImage.getWidth(null) * scaleFactor)/100;
             int sliderHeight = (int) (bufferedImage.getHeight(null) * scaleFactor)/100;

             imageX = panelWidth/2 - sliderWidth/2;
             imageY = panelHeight/2 - sliderHeight/2;


             g.drawImage(template, imageX, imageY, sliderWidth, sliderHeight, null);
             Image image = new ImageIcon(template.getScaledInstance(sliderWidth, sliderHeight, Image.SCALE_SMOOTH)).getImage();
             textLabel.setText(Integer.toString(scaleFactor) + ": " + Integer.toString(d.getWidth()) + " x " + Integer.toString(d.getHeight()));
             this.add(textLabel);
            }

            public Dimension getImageSize() {
              return new Dimension(imageX, imageY);
            }

          };

          final JSlider slider = new JSlider(0, 200);
          slider.addChangeListener(new ChangeListener() {
            public final void stateChanged(ChangeEvent e) {
              scaleFactor = slider.getValue();
              p.repaint();
            }
          });



          JPanel panel = new JPanel();
          panel.add(slider);
          textLabel = new JLabel(Integer.toString(d.getWidth()) + " x " + Integer.toString(d.getHeight()));

          getContentPane().add(p, BorderLayout.CENTER);
          getContentPane().add(panel, BorderLayout.SOUTH);
          setVisible(true);


        } else if (status == d.CANCEL_OPTION) {
          System.out.println("You cancelled operation");
        }

      }
    });
    menu.add(openItem);
  }

  public static void main(String[] args) {
    JFrame iframe = new ImageViewerGUI();
    iframe.setVisible(true);
  }
}
 
S

SlaterB

Gast
hmm, ja, das Programm skaliert bei dir auch einigermaßen das Bild,

grundsätzlich solltest du vermeiden, erst in Listenern neue Panel zu erstellen usw.,
lieber am Anfang die GUI festlegen, wenn sich mehrere Fenster abwechseln, dann z.B. CardLayout,

ganz schlimm ist, in paintComponent() noch per add() Komponenten hinzuzufügen,
das kann 20x pro Sekunde doch gar keinen Sinn machen, im Falle des TextFeldes bei dir auch gar nicht nötig

-----

Speichern fehlt komplett, dort dann erst das BufferedImage erstellen und darauf das template malen,
scaleFactor bestimmt den draw-Befehl und vorher vielleicht die Höhe/Breite des BufferedImages

wie man das BufferedImage grundsätzlich speichert kann ich aber gar nicht sagen, wenn du es selber noch nicht weißt und niemand anders Code liefert,
dann erstmal irgendein Beispiel im Internet suchen
 

innoc

Aktives Mitglied
Hallo SlaterB,

bevor ich den Slider eingefügt habe, konnte ich das Bild noch problemlos abspeichern. Über Edit --> Resize konnte ich auch das Bild neu skalieren und über "Save as" als Kopie abspeichern. Da sah das Programm noch wie folgt aus:

Java:
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import javax.imageio.*;
import javax.imageio.stream.*;
import javax.swing.*;
import javax.swing.filechooser.FileFilter;

public class ImageViewerGUI extends BaseFrame {
  JFileChooser d;
  BufferedImage bufferedImage;
  JPanel p;
  ScaledImage si = new ScaledImage();

  public ImageViewerGUI() {

    // create a file chooser
    d = new JFileChooser();
    d.setFileFilter(new FileFilter() {
      public boolean accept(File f) {
        return f.isDirectory() || f.getName().toLowerCase().endsWith(".jpg");
      }
      public String getDescription() {
        return "*.jpg";
      }
    });
    
    // Create menu bar
    JMenuBar mbar = new JMenuBar();
    setJMenuBar(mbar);

    // Build the File-Menu
    JMenu menu = new JMenu("File");
    menu.setMnemonic(KeyEvent.VK_F);
    mbar.add(menu);

    // The Open JMenuItem
    JMenuItem openItem = new JMenuItem("Open", KeyEvent.VK_O);
    openItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, InputEvent.CTRL_MASK));
    openItem.getAccessibleContext().setAccessibleDescription("Open a new image file");
    openItem.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {

        int status = d.showOpenDialog(null);
        if (status == d.APPROVE_OPTION) {
          File file = d.getSelectedFile();
          final Image template = new ImageIcon(Toolkit.getDefaultToolkit().getImage(file.getAbsolutePath())).getImage();

          // Create the buffered image
          // notice: bufferedImage is a bufferedImage type
          bufferedImage = new BufferedImage(template.getWidth(null), template.getHeight(null), BufferedImage.TYPE_INT_RGB);


          // Copy image to buffered image
          Graphics g = bufferedImage.getGraphics();

          // Clear background and paint the image
          g.setColor(Color.black);
          g.fillRect(0, 0, template.getWidth(null), template.getHeight(null));
          g.drawImage(template, 0, 0, null);

          p = new JPanel();
          p.add(new JLabel(new ImageIcon(bufferedImage)));
          getContentPane().add(p, BorderLayout.CENTER);
          setVisible(true);

          si.setScaledImage(bufferedImage);
        } else if (status == d.CANCEL_OPTION) {
          System.out.println("You cancelled operation");
        }

      }
    });
    menu.add(openItem);

    JMenuItem saveItem = new JMenuItem("Save", KeyEvent.VK_S);
    saveItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, ActionEvent.CTRL_MASK));
    saveItem.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent ie) {
        try {
          Iterator it = ImageIO.getImageWritersByFormatName("jpeg");
          ImageWriter writer = (ImageWriter)it.next();
          // instantiate an ImageWriterParam object with default compression options
          ImageWriteParam iwp = writer.getDefaultWriteParam();
          iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
          iwp.setCompressionQuality(1); // an integer between 0 and 1
          File file = new File(d.getSelectedFile().getName());
          FileImageOutputStream output = new FileImageOutputStream(file);
          writer.setOutput(output);
          IIOImage image = new IIOImage(si.getScaledImage(), null, null);
          writer.write(null, image, iwp);
          writer.dispose();
        } catch (IOException ex) {
          ex.printStackTrace();
        }
      }
    });
    menu.add(saveItem);

    JMenuItem saveAsItem = new JMenuItem("Save As...", KeyEvent.VK_A);
    saveAsItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A, ActionEvent.CTRL_MASK));
    saveAsItem.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent sa) {
        int status = d.showSaveDialog(null);
        if (status == d.APPROVE_OPTION) {
          try {
            Iterator it = ImageIO.getImageWritersByFormatName("jpeg");
            ImageWriter writer = (ImageWriter)it.next();
            // instantiate an ImageWriterParam object with default compression options
            ImageWriteParam iwp = writer.getDefaultWriteParam();
            iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
            iwp.setCompressionQuality(1); // an integer between 0 and 1
            File file = d.getSelectedFile();
            FileImageOutputStream output = new FileImageOutputStream(file);
            writer.setOutput(output);
            IIOImage image = new IIOImage(si.getScaledImage(), null, null);
            writer.write(null, image, iwp);
            writer.dispose();
          } catch (IOException ex) {
            ex.printStackTrace();
          }
        } else if (status == d.CANCEL_OPTION) {
          System.out.println("You cancelled operation");
        }
      }
    });
    menu.add(saveAsItem);


    JMenuItem exitItem = new JMenuItem("Exit", KeyEvent.VK_E);
    exitItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, ActionEvent.CTRL_MASK));
    exitItem.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent qe) {
        System.exit(0);
      }
    });
    menu.add(exitItem);

    // Build second menu in menu bar
    JMenu optionsMenu = new JMenu("Edit");
    optionsMenu.setMnemonic(KeyEvent.VK_P);
    optionsMenu.getAccessibleContext().setAccessibleDescription("Set Options");
    mbar.add(optionsMenu);

    JMenuItem resizeItem = new JMenuItem("Resize", KeyEvent.VK_R);
    resizeItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_R, ActionEvent.CTRL_MASK));
    resizeItem.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        String width = JOptionPane.showInputDialog((Component)e.getSource(), "new Image Width");
        if (width != null && !width.equals("")) {
          JOptionPane.showMessageDialog((Component)e.getSource(), "Preferred Image Width: " + width);
          int newWidth = Integer.parseInt(width);
          si.scaleImage(newWidth);
          p = new JPanel();
          p.add(new JLabel(new ImageIcon(si.getScaledImage())));
          getContentPane().add(p, BorderLayout.CENTER);
          setVisible(true);
        }
      }
    });
    optionsMenu.add(resizeItem);

  }

  public static void main(String[] args) {
    JFrame iframe = new ImageViewerGUI();
    iframe.setVisible(true);
  }
}

Ich habe dabei auf eine Hilfsklasse in dem separaten File ScaledImage.java zurückgegriffen. Hier lautet der Programmcode:
Java:
import java.awt.*;
import java.awt.image.*;
import javax.swing.*;

public class ScaledImage extends JPanel {
  private BufferedImage scaledImage;
  int width, height;

  public void setScaledImage(BufferedImage bufferedImage) {
    scaledImage = bufferedImage;
    width = scaledImage.getWidth();
    height = scaledImage.getHeight();
  }

  public BufferedImage getScaledImage() {
    return scaledImage;
  }

  public BufferedImage scaleImage(int newWidth) {
    int oldWidth = scaledImage.getWidth();
    int oldHeight = scaledImage.getHeight();
    int newHeight = (newWidth * oldHeight)/oldWidth;
    Image resizedImage = scaledImage.getScaledInstance(newWidth, newHeight, Image.SCALE_SMOOTH);
    
    // This code ensures that all the pixels in the image are loaded
    Image temp = new ImageIcon(resizedImage).getImage();

    // Create a buffered Image
    BufferedImage bufferedImage = new BufferedImage(temp.getWidth(null), temp.getHeight(null), BufferedImage.TYPE_INT_RGB);

    // Copy image to buffered image
    Graphics g = bufferedImage.getGraphics();

    // Clear background and paint the image
    g.setColor(Color.black);
    g.fillRect(0, 0, temp.getWidth(null), temp.getHeight(null));
    g.drawImage(temp, 0, 0, null);

    scaledImage = bufferedImage;
    return scaledImage;
  }

  protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    if (scaledImage != null) g.drawImage(scaledImage, 0, 0, this);
  }
}

Und um das Ganze noch zu komplettieren, hier die Klasse BaseFrame:
Java:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

class BaseFrame extends JFrame {

  BaseFrame() {
    addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
    });
    setSize(800, 500);
    setLocationRelativeTo(null);
  }
  
}

Kann sein, dass das alles etwas umständlich ist, aber außer noch ein paar Exceptions rein, ergab das ein lauffähiges Programm. Die Schwierigkeiten fingen dann mit dem Slider an. Egal was ich bisher an ScaledImage sendete, ergab nur Müll, entweder nur einen schwarzen Rahmen oder ein abgeschnittenes Bild oder schon das verkleinerte Bild, aber mit einem schwarzen Rahmen der Größe vom Panel. Daher ist es mir klar, dass das Problem irgendwie von der Definition eines Containers abhängt, Panel, Frame, Label oder was anderes, in den ich das BufferedImage reinpacke und der sich dynamisch der Skalierung mittels Slider anpasst. Leider habe ich jedoch keine Ahnung, wie ich das umsetzen kann, bisher habe ich auch nur mit Border- oder Gridlayout gearbeitet. Über Vorschläge wäre ich sehr dankbar.
 
S

SlaterB

Gast
sieht ja alles nicht schlecht aus, besser aber noch:

bei den Speicher-Methoden close() auf die Streams aufrufen, ansonsten kann das evtl. zu Fehlern führen, mindestens aber die Datei für andere Programme sperren unter Windows

die save()-Methode verwendet nur den Dateinamen, speichert im Arbeitsverzeichnis des Programms, nicht im Originalverzeichnis des Bildes,

und wieder gilt: bei resise() wird ein neues Panel erstellt, wieso? das alte geht doch genauso..

-----

jedenfalls hast du hinsichtlich BufferedImage eine günstige Verteilung: scaleImage() berechnet ein neues Bild, paintComponent() malt dieses, ist ansonsten leer, super,

in deinen neueren Programmen ist das nicht mehr so, da gibt es keine Methode die nur genau ein neues BufferedImage befüllt,
und paintComponent() macht dagegen soviel Arbeit, speichert das neue Bild aber nirgendwo, so dass eine save-Methode es abfragen könnte,
wieso dieser Wechsel?
gehe zurück auf scaleImage() + paintComponent()

---

falls du getScaledInstance() unbedingt brauchst:
Java:
Image image = new ImageIcon(altesBild.getScaledInstance(w, h, Image.SCALE_SMOOTH)).getImage();

ist das nicht dasselbe wie
Image image = altesBild.getScaledInstance(w, h, Image.SCALE_SMOOTH);
?
dieses Image könntest du jedenfalls auf ein BufferedImage malen so wie du es in paintComponent() malst,
dann hast du wieder ein BufferedImage
 

innoc

Aktives Mitglied
wenn das ältere Design vor dem Slider im großen und ganzen in Ordnung ist, dann stellt sich für mich die Frage, an welcher Stelle ich den Slider einfügen kann. Um den Slider benuzen zu können, habe ich letztlich die ganzen Änderungen durchgeführt. Muss ich nicht für den Slider ein zusätzliches JPanel mit einer paintComponent()-Methode erstellen? Wenn das nicht der Fall sein sollte, wie kann ich es anstellen, dass der Slider in ImageViewerGUI.java dann Zugriff auf die paintComponent()-Methode von ScaledImage erhält.
 
S

SlaterB

Gast
> dann Zugriff auf die paintComponent()-Methode von ScaledImage erhält.
diesen Zugriff brauchst du nicht,

den JSlider fügst du erstmal irgendwo in der GUI ein, dass du damit noch grundsätzlich Probleme hast habe ich ja schon 2x erwähnt,
kein Listener sollte neue Panel erstellen usw.

wenn der JSlider funktioniert und Events liefert, was unterscheidet diese dann von dem resize()-Button?
genausogut könnte der JSlider-Listener
> si.scaleImage(newWidth);
aufrufen, der Einfachheit halber erstmal direkt den Slider-Value als Width verwenden,
später kann man es komplizierter machen, aber höchstens in einer Methode ähnlich scaleImage(),
nicht in paintComponent(), die ist mir 3 Zeilen wahrscheinlich bis auf weiteres groß genug
 

innoc

Aktives Mitglied
Danke SlaterB für die Tipps. Muss mich noch mit ein paar Smalltalk-Aufgaben herumschlagen und werde mich danach dransetzen und mich dann sicher wieder melden.
 

innoc

Aktives Mitglied
Hallo wieder,

ich habe nun versucht, die Vorschläge von SlaterB umzusetzen, und bekomme jetzt auch ohne neues JPanel das Bild mit dem JSlider skaliert. Dafür rufe ich die Methode si.scaleImage() nun direkt im Slider auf. Leider bekomme ich das skalierte Bild jedoch nur angezeigt, wenn ich ebenfalls im Slider das alte JPanel mit dem Originalbild überschreibe. Das hat natürlich unhübsche Nebeneffekte, denn das nicht skalierte Originalbild liegt noch unter dem neu skalierten Bild, bzw. das neu gezeichnete JPanel liegt über dem alten JPanel, dies wird deutlich, wenn ich z.B. das Bild skaliere mit dem JSlider skaliere und danach das Fenster größer ziehe. Das gleiche Problem habe ich, wenn ich das Bild abspeichere. Daher meine Frage: Wie schaffe ich es das im JPanel angezeigte Bild neu zu skalieren, statt das JPanel nur mit skalierten Kopien von dem Bild zu überlagern? Kann ich dieses Problem nur mit CardLayout lösen, oder gibt es da andere Möglichkeiten?
Anbei der aktuelle Programmcode von ImageViewerGUI.java (ScaleImage.java und BaseFrame.java habe ich nicht verändert):
Java:
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import javax.imageio.*;
import javax.imageio.stream.*;
import javax.swing.*;
import javax.swing.filechooser.FileFilter;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;


public class ImageViewerGUI extends BaseFrame {
  JFileChooser d;
  BufferedImage bufferedImage;
  JPanel p;
  ScaledImage si = new ScaledImage();
  int scaleFactor = 100;
  JLabel textlabel;

  public ImageViewerGUI() {

    // create a file chooser
    d = new JFileChooser();
    d.setFileFilter(new FileFilter() {
      public boolean accept(File f) {
        return f.isDirectory() || f.getName().toLowerCase().endsWith(".jpg");
      }
      public String getDescription() {
        return "*.jpg";
      }
    });
    
    // Create menu bar
    JMenuBar mbar = new JMenuBar();
    setJMenuBar(mbar);

    // Build the File-Menu
    JMenu menu = new JMenu("File");
    menu.setMnemonic(KeyEvent.VK_F);
    mbar.add(menu);

    // The Open JMenuItem
    JMenuItem openItem = new JMenuItem("Open", KeyEvent.VK_O);
    openItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, InputEvent.CTRL_MASK));
    openItem.getAccessibleContext().setAccessibleDescription("Open a new image file");
    openItem.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {

        int status = d.showOpenDialog(null);
        if (status == d.APPROVE_OPTION) {
          File file = d.getSelectedFile();
          final Image template = new ImageIcon(Toolkit.getDefaultToolkit().getImage(file.getAbsolutePath())).getImage();

          // Create the buffered image
          // notice: bufferedImage is a bufferedImage type
          bufferedImage = new BufferedImage(template.getWidth(null), template.getHeight(null), BufferedImage.TYPE_INT_RGB);

          si.setScaledImage(bufferedImage);
          si.scaleImage((bufferedImage.getWidth() * scaleFactor)/100);

          // Copy image to scaled buffered image instance
          Graphics g = si.getScaledImage().getGraphics();

          // Clear background and paint the image
          g.setColor(Color.black);
          g.fillRect(0, 0, template.getWidth(null), template.getHeight(null));
          g.drawImage(template, 0, 0, null);
          g.dispose();

          final JSlider slider = new JSlider(0, 200);
          slider.addChangeListener(new ChangeListener() {
            public final void stateChanged(ChangeEvent e) {
              if (!slider.getValueIsAdjusting()) {
                scaleFactor = slider.getValue();
                String str = Integer.toString(scaleFactor);
                textlabel.setText(str);
                si.scaleImage((bufferedImage.getWidth() * scaleFactor)/100);
                p = new JPanel();
                p.add(new JLabel(new ImageIcon(si.getScaledImage())));
                getContentPane().add(p, BorderLayout.CENTER);
                setVisible(true);
              }
            }
          });


          p = new JPanel();
          p.add(new JLabel(new ImageIcon(si.getScaledImage())));
          getContentPane().add(p, BorderLayout.CENTER);
          textlabel = new JLabel(Integer.toString(scaleFactor));
          JPanel sliderpanel = new JPanel();
          sliderpanel.add(slider);
          sliderpanel.add(textlabel);
          getContentPane().add(sliderpanel, BorderLayout.SOUTH);
          setVisible(true);

        } else if (status == d.CANCEL_OPTION) {
          System.out.println("You cancelled operation");
        }

      }
    });
    menu.add(openItem);

    JMenuItem saveItem = new JMenuItem("Save", KeyEvent.VK_S);
    saveItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, ActionEvent.CTRL_MASK));
    saveItem.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent ie) {
        try {
          Iterator it = ImageIO.getImageWritersByFormatName("jpeg");
          ImageWriter writer = (ImageWriter)it.next();
          // instantiate an ImageWriterParam object with default compression options
          ImageWriteParam iwp = writer.getDefaultWriteParam();
          iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
          iwp.setCompressionQuality(1); // an integer between 0 and 1
          File file = new File(d.getSelectedFile().getAbsolutePath());
          FileImageOutputStream output = new FileImageOutputStream(file);
          writer.setOutput(output);
          IIOImage image = new IIOImage(si.getScaledImage(), null, null);
          writer.write(null, image, iwp);
          output.flush();
          writer.dispose();
          // close the stream to give other programs access to the image
          output.close();
        } catch (IOException ex) {
          ex.printStackTrace();
        }
      }
    });
    menu.add(saveItem);

    JMenuItem saveAsItem = new JMenuItem("Save As...", KeyEvent.VK_A);
    saveAsItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A, ActionEvent.CTRL_MASK));
    saveAsItem.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent sa) {
        int status = d.showSaveDialog(null);
        if (status == d.APPROVE_OPTION) {
          try {
            Iterator it = ImageIO.getImageWritersByFormatName("jpeg");
            ImageWriter writer = (ImageWriter)it.next();
            // instantiate an ImageWriterParam object with default compression options
            ImageWriteParam iwp = writer.getDefaultWriteParam();
            iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
            iwp.setCompressionQuality(1); // an integer between 0 and 1
            File file = d.getSelectedFile();
            FileImageOutputStream output = new FileImageOutputStream(file);
            writer.setOutput(output);
            IIOImage image = new IIOImage(si.getScaledImage(), null, null);
            writer.write(null, image, iwp);
            output.flush();
            writer.dispose();
            // close the stream to give other programs access to the image
            output.close();
          } catch (IOException ex) {
            ex.printStackTrace();
          }
        } else if (status == d.CANCEL_OPTION) {
          System.out.println("You cancelled operation");
        }
      }
    });
    menu.add(saveAsItem);


    JMenuItem exitItem = new JMenuItem("Exit", KeyEvent.VK_E);
    exitItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, ActionEvent.CTRL_MASK));
    exitItem.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent qe) {
        System.exit(0);
      }
    });
    menu.add(exitItem);

    // Build second menu in menu bar
    JMenu optionsMenu = new JMenu("Edit");
    optionsMenu.setMnemonic(KeyEvent.VK_P);
    optionsMenu.getAccessibleContext().setAccessibleDescription("Set Options");
    mbar.add(optionsMenu);

    JMenuItem resizeItem = new JMenuItem("Resize", KeyEvent.VK_R);
    resizeItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_R, ActionEvent.CTRL_MASK));
    resizeItem.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        String width = JOptionPane.showInputDialog((Component)e.getSource(), "new Image Width");
        if (width != null && !width.equals("")) {
          JOptionPane.showMessageDialog((Component)e.getSource(), "Preferred Image Width: " + width);
          int newWidth = Integer.parseInt(width);
          si.scaleImage(newWidth);
          p = new JPanel();
          p.add(new JLabel(new ImageIcon(si.getScaledImage())));
          getContentPane().add(p, BorderLayout.CENTER);
          setVisible(true);
        }
      }
    });
    optionsMenu.add(resizeItem);

  }

  public static void main(String[] args) {
    JFrame iframe = new ImageViewerGUI();
    iframe.setVisible(true);
  }
}
 
S

SlaterB

Gast
ich weiß nicht was deine Einstellung ist, weiterhin deutlich benannte unnötige Fehler zu wiederholen,
hier zwei Korrektur-Varianten, aber was nützt es auf so deutliche Dinge überhaupt noch hinzuweisen?

---

nebenbei: du merkst dir bisher nicht das Originalbild sondern skalierst immer auf dasselbe, wenn man einmal auf 5% runter geht und danach wieder hoch, ist das Bild ziemlich verwaschen,
netter Effekt durchaus

-----

hier mit Panel und Label und Icon: alles nur einmal erstellen, was letztlich zumindest bis zum Label geht, das Icon neu zu erstellen ist ertragbar,
wenn du weiterhin lieber neue Panels, neue TextFelder, neue Labels erstellst dann zumindest die alten vorher removen!

Java:
public class Test
{

    public static void main(String[] args)
    {
        JFrame iframe = new ImageViewerGUI();
        iframe.setVisible(true);
    }
}


class ImageViewerGUI
    extends BaseFrame
{
    JFileChooser d;
    BufferedImage bufferedImage;
    final JPanel p;
    final JLabel l;
    ScaledImage si = new ScaledImage();
    int scaleFactor = 100;
    final JLabel textlabel;

    public ImageViewerGUI()
    {
        l = new JLabel();
        p = new JPanel();
        p.add(l);
        getContentPane().add(p, BorderLayout.CENTER);

        final JSlider slider = new JSlider(0, 200);
        slider.addChangeListener(new ChangeListener()
            {
                public final void stateChanged(ChangeEvent e)
                {
                    if (!slider.getValueIsAdjusting())
                    {
                        scaleFactor = slider.getValue();
                        String str = Integer.toString(scaleFactor);
                        textlabel.setText(str);
                        si.scaleImage((bufferedImage.getWidth() * scaleFactor) / 100);
                        l.setIcon(new ImageIcon(si.getScaledImage()));
                    }
                }
            });
        JPanel sliderpanel = new JPanel();
        sliderpanel.add(slider);
        textlabel = new JLabel(Integer.toString(scaleFactor));
        sliderpanel.add(textlabel);
        getContentPane().add(sliderpanel, BorderLayout.SOUTH);

        // create a file chooser
        d = new JFileChooser();
        d.setFileFilter(new FileFilter()
            {
                public boolean accept(File f)
                {
                    return f.isDirectory() || f.getName().toLowerCase().endsWith(".jpg");
                }

                public String getDescription()
                {
                    return "*.jpg";
                }
            });

        // Create menu bar
        JMenuBar mbar = new JMenuBar();
        setJMenuBar(mbar);

        // Build the File-Menu
        JMenu menu = new JMenu("File");
        menu.setMnemonic(KeyEvent.VK_F);
        mbar.add(menu);

        // The Open JMenuItem
        JMenuItem openItem = new JMenuItem("Open", KeyEvent.VK_O);
        openItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, InputEvent.CTRL_MASK));
        openItem.getAccessibleContext().setAccessibleDescription("Open a new image file");
        openItem.addActionListener(new ActionListener()
            {
                public void actionPerformed(ActionEvent e)
                {

                    int status = d.showOpenDialog(null);
                    if (status == d.APPROVE_OPTION)
                    {
                        File file = d.getSelectedFile();
                        final Image template = new ImageIcon(Toolkit.getDefaultToolkit().getImage(file.getAbsolutePath())).getImage();

                        // Create the buffered image
                        // notice: bufferedImage is a bufferedImage type
                        bufferedImage = new BufferedImage(template.getWidth(null), template.getHeight(null),
                                                          BufferedImage.TYPE_INT_RGB);

                        si.setScaledImage(bufferedImage);
                        si.scaleImage((bufferedImage.getWidth() * scaleFactor) / 100);

                        // Copy image to scaled buffered image instance
                        Graphics g = si.getScaledImage().getGraphics();

                        // Clear background and paint the image
                        g.setColor(Color.black);
                        g.fillRect(0, 0, template.getWidth(null), template.getHeight(null));
                        g.drawImage(template, 0, 0, null);
                        g.dispose();


                        textlabel.setText(Integer.toString(scaleFactor));
                        l.setIcon(new ImageIcon(si.getScaledImage()));
                    }
                    else if (status == d.CANCEL_OPTION)
                    {
                        System.out.println("You cancelled operation");
                    }

                }
            });
        menu.add(openItem);

        JMenuItem saveItem = new JMenuItem("Save", KeyEvent.VK_S);
        saveItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, ActionEvent.CTRL_MASK));
        saveItem.addActionListener(new ActionListener()
            {
                public void actionPerformed(ActionEvent ie)
                {
                    try
                    {
                        Iterator it = ImageIO.getImageWritersByFormatName("jpeg");
                        ImageWriter writer = (ImageWriter)it.next();
                        // instantiate an ImageWriterParam object with default compression
                        // options
                        ImageWriteParam iwp = writer.getDefaultWriteParam();
                        iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
                        iwp.setCompressionQuality(1); // an integer between 0 and 1
                        File file = new File(d.getSelectedFile().getAbsolutePath());
                        FileImageOutputStream output = new FileImageOutputStream(file);
                        writer.setOutput(output);
                        IIOImage image = new IIOImage(si.getScaledImage(), null, null);
                        writer.write(null, image, iwp);
                        output.flush();
                        writer.dispose();
                        // close the stream to give other programs access to the image
                        output.close();
                    }
                    catch (IOException ex)
                    {
                        ex.printStackTrace();
                    }
                }
            });
        menu.add(saveItem);

        JMenuItem saveAsItem = new JMenuItem("Save As...", KeyEvent.VK_A);
        saveAsItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A, ActionEvent.CTRL_MASK));
        saveAsItem.addActionListener(new ActionListener()
            {
                public void actionPerformed(ActionEvent sa)
                {
                    int status = d.showSaveDialog(null);
                    if (status == d.APPROVE_OPTION)
                    {
                        try
                        {
                            Iterator it = ImageIO.getImageWritersByFormatName("jpeg");
                            ImageWriter writer = (ImageWriter)it.next();
                            // instantiate an ImageWriterParam object with default
                            // compression options
                            ImageWriteParam iwp = writer.getDefaultWriteParam();
                            iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
                            iwp.setCompressionQuality(1); // an integer between 0 and 1
                            File file = d.getSelectedFile();
                            FileImageOutputStream output = new FileImageOutputStream(file);
                            writer.setOutput(output);
                            IIOImage image = new IIOImage(si.getScaledImage(), null, null);
                            writer.write(null, image, iwp);
                            output.flush();
                            writer.dispose();
                            // close the stream to give other programs access to the image
                            output.close();
                        }
                        catch (IOException ex)
                        {
                            ex.printStackTrace();
                        }
                    }
                    else if (status == d.CANCEL_OPTION)
                    {
                        System.out.println("You cancelled operation");
                    }
                }
            });
        menu.add(saveAsItem);


        JMenuItem exitItem = new JMenuItem("Exit", KeyEvent.VK_E);
        exitItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, ActionEvent.CTRL_MASK));
        exitItem.addActionListener(new ActionListener()
            {
                public void actionPerformed(ActionEvent qe)
                {
                    System.exit(0);
                }
            });
        menu.add(exitItem);

        // Build second menu in menu bar
        JMenu optionsMenu = new JMenu("Edit");
        optionsMenu.setMnemonic(KeyEvent.VK_P);
        optionsMenu.getAccessibleContext().setAccessibleDescription("Set Options");
        mbar.add(optionsMenu);

        JMenuItem resizeItem = new JMenuItem("Resize", KeyEvent.VK_R);
        resizeItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_R, ActionEvent.CTRL_MASK));
        resizeItem.addActionListener(new ActionListener()
            {
                public void actionPerformed(ActionEvent e)
                {
                    String width = JOptionPane.showInputDialog((Component)e.getSource(), "new Image Width");
                    if (width != null && !width.equals(""))
                    {
                        JOptionPane.showMessageDialog((Component)e.getSource(), "Preferred Image Width: " + width);
                        int newWidth = Integer.parseInt(width);
                        si.scaleImage(newWidth);
                        l.setIcon(new ImageIcon(si.getScaledImage()));
                    }
                }
            });
        optionsMenu.add(resizeItem);

    }

    public static void main(String[] args)
    {
        JFrame iframe = new ImageViewerGUI();
        iframe.setVisible(true);
    }
}


class BaseFrame
    extends JFrame
{

    BaseFrame()
    {
        addWindowListener(new WindowAdapter()
            {
                public void windowClosing(WindowEvent e)
                {
                    System.exit(0);
                }
            });
        setSize(800, 500);
        setLocationRelativeTo(null);
    }

}


class ScaledImage
    extends JPanel
{
    private BufferedImage scaledImage;
    int width, height;

    public void setScaledImage(BufferedImage bufferedImage)
    {
        scaledImage = bufferedImage;
        width = scaledImage.getWidth();
        height = scaledImage.getHeight();
    }

    public BufferedImage getScaledImage()
    {
        return scaledImage;
    }

    public BufferedImage scaleImage(int newWidth)
    {
        int oldWidth = scaledImage.getWidth();
        int oldHeight = scaledImage.getHeight();
        int newHeight = (newWidth * oldHeight) / oldWidth;
        Image resizedImage = scaledImage.getScaledInstance(newWidth, newHeight, Image.SCALE_SMOOTH);

        // This code ensures that all the pixels in the image are loaded
        Image temp = new ImageIcon(resizedImage).getImage();

        // Create a buffered Image
        BufferedImage bufferedImage = new BufferedImage(temp.getWidth(null), temp.getHeight(null), BufferedImage.TYPE_INT_RGB);

        // Copy image to buffered image
        Graphics g = bufferedImage.getGraphics();

        // Clear background and paint the image
        g.setColor(Color.black);
        g.fillRect(0, 0, temp.getWidth(null), temp.getHeight(null));
        g.drawImage(temp, 0, 0, null);

        scaledImage = bufferedImage;
        return scaledImage;
    }

    protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        if (scaledImage != null) g.drawImage(scaledImage, 0, 0, this);
    }
}

------

und hier noch eine Variante nur mit ScaledImage, das ist doch extra ein Panel mit paint-Methode, wieso das nicht nutzen sondern Label + Icon?
das Bild wird zwar nicht zentriert gemalt, aber das kann man ja noch verbessern

siehe deine Code-Versuche ganz am Anfang bzw. mein erstes Post


Java:
public class Test
{

    public static void main(String[] args)
    {
        JFrame iframe = new ImageViewerGUI();
        iframe.setVisible(true);
    }
}


class ImageViewerGUI
    extends BaseFrame
{
    JFileChooser d;
    BufferedImage bufferedImage;
    ScaledImage si = new ScaledImage();
    int scaleFactor = 100;
    final JLabel textlabel;

    public ImageViewerGUI()
    {
        getContentPane().add(si, BorderLayout.CENTER);

        final JSlider slider = new JSlider(0, 200);
        slider.addChangeListener(new ChangeListener()
            {
                public final void stateChanged(ChangeEvent e)
                {
                    if (!slider.getValueIsAdjusting())
                    {
                        scaleFactor = slider.getValue();
                        String str = Integer.toString(scaleFactor);
                        textlabel.setText(str);
                        si.scaleImage((bufferedImage.getWidth() * scaleFactor) / 100);

                        validate();
                        repaint();
                    }
                }
            });
        JPanel sliderpanel = new JPanel();
        sliderpanel.add(slider);
        textlabel = new JLabel(Integer.toString(scaleFactor));
        sliderpanel.add(textlabel);
        getContentPane().add(sliderpanel, BorderLayout.SOUTH);

        // create a file chooser
        d = new JFileChooser();
        d.setFileFilter(new FileFilter()
            {
                public boolean accept(File f)
                {
                    return f.isDirectory() || f.getName().toLowerCase().endsWith(".jpg");
                }

                public String getDescription()
                {
                    return "*.jpg";
                }
            });

        // Create menu bar
        JMenuBar mbar = new JMenuBar();
        setJMenuBar(mbar);

        // Build the File-Menu
        JMenu menu = new JMenu("File");
        menu.setMnemonic(KeyEvent.VK_F);
        mbar.add(menu);

        // The Open JMenuItem
        JMenuItem openItem = new JMenuItem("Open", KeyEvent.VK_O);
        openItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, InputEvent.CTRL_MASK));
        openItem.getAccessibleContext().setAccessibleDescription("Open a new image file");
        openItem.addActionListener(new ActionListener()
            {
                public void actionPerformed(ActionEvent e)
                {

                    int status = d.showOpenDialog(null);
                    if (status == d.APPROVE_OPTION)
                    {
                        File file = d.getSelectedFile();
                        final Image template = new ImageIcon(Toolkit.getDefaultToolkit().getImage(file.getAbsolutePath())).getImage();

                        // Create the buffered image
                        // notice: bufferedImage is a bufferedImage type
                        bufferedImage = new BufferedImage(template.getWidth(null), template.getHeight(null),
                                                          BufferedImage.TYPE_INT_RGB);

                        si.setScaledImage(bufferedImage);
                        si.scaleImage((bufferedImage.getWidth() * scaleFactor) / 100);

                        // Copy image to scaled buffered image instance
                        Graphics g = si.getScaledImage().getGraphics();

                        // Clear background and paint the image
                        g.setColor(Color.black);
                        g.fillRect(0, 0, template.getWidth(null), template.getHeight(null));
                        g.drawImage(template, 0, 0, null);
                        g.dispose();


                        textlabel.setText(Integer.toString(scaleFactor));
                        validate();
                        repaint();
                    }
                    else if (status == d.CANCEL_OPTION)
                    {
                        System.out.println("You cancelled operation");
                    }

                }
            });
        menu.add(openItem);

        JMenuItem saveItem = new JMenuItem("Save", KeyEvent.VK_S);
        saveItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, ActionEvent.CTRL_MASK));
        saveItem.addActionListener(new ActionListener()
            {
                public void actionPerformed(ActionEvent ie)
                {
                    try
                    {
                        Iterator it = ImageIO.getImageWritersByFormatName("jpeg");
                        ImageWriter writer = (ImageWriter)it.next();
                        // instantiate an ImageWriterParam object with default compression
                        // options
                        ImageWriteParam iwp = writer.getDefaultWriteParam();
                        iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
                        iwp.setCompressionQuality(1); // an integer between 0 and 1
                        File file = new File(d.getSelectedFile().getAbsolutePath());
                        FileImageOutputStream output = new FileImageOutputStream(file);
                        writer.setOutput(output);
                        IIOImage image = new IIOImage(si.getScaledImage(), null, null);
                        writer.write(null, image, iwp);
                        output.flush();
                        writer.dispose();
                        // close the stream to give other programs access to the image
                        output.close();
                    }
                    catch (IOException ex)
                    {
                        ex.printStackTrace();
                    }
                }
            });
        menu.add(saveItem);

        JMenuItem saveAsItem = new JMenuItem("Save As...", KeyEvent.VK_A);
        saveAsItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A, ActionEvent.CTRL_MASK));
        saveAsItem.addActionListener(new ActionListener()
            {
                public void actionPerformed(ActionEvent sa)
                {
                    int status = d.showSaveDialog(null);
                    if (status == d.APPROVE_OPTION)
                    {
                        try
                        {
                            Iterator it = ImageIO.getImageWritersByFormatName("jpeg");
                            ImageWriter writer = (ImageWriter)it.next();
                            // instantiate an ImageWriterParam object with default
                            // compression options
                            ImageWriteParam iwp = writer.getDefaultWriteParam();
                            iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
                            iwp.setCompressionQuality(1); // an integer between 0 and 1
                            File file = d.getSelectedFile();
                            FileImageOutputStream output = new FileImageOutputStream(file);
                            writer.setOutput(output);
                            IIOImage image = new IIOImage(si.getScaledImage(), null, null);
                            writer.write(null, image, iwp);
                            output.flush();
                            writer.dispose();
                            // close the stream to give other programs access to the image
                            output.close();
                        }
                        catch (IOException ex)
                        {
                            ex.printStackTrace();
                        }
                    }
                    else if (status == d.CANCEL_OPTION)
                    {
                        System.out.println("You cancelled operation");
                    }
                }
            });
        menu.add(saveAsItem);


        JMenuItem exitItem = new JMenuItem("Exit", KeyEvent.VK_E);
        exitItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, ActionEvent.CTRL_MASK));
        exitItem.addActionListener(new ActionListener()
            {
                public void actionPerformed(ActionEvent qe)
                {
                    System.exit(0);
                }
            });
        menu.add(exitItem);

        // Build second menu in menu bar
        JMenu optionsMenu = new JMenu("Edit");
        optionsMenu.setMnemonic(KeyEvent.VK_P);
        optionsMenu.getAccessibleContext().setAccessibleDescription("Set Options");
        mbar.add(optionsMenu);

        JMenuItem resizeItem = new JMenuItem("Resize", KeyEvent.VK_R);
        resizeItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_R, ActionEvent.CTRL_MASK));
        resizeItem.addActionListener(new ActionListener()
            {
                public void actionPerformed(ActionEvent e)
                {
                    String width = JOptionPane.showInputDialog((Component)e.getSource(), "new Image Width");
                    if (width != null && !width.equals(""))
                    {
                        JOptionPane.showMessageDialog((Component)e.getSource(), "Preferred Image Width: " + width);
                        int newWidth = Integer.parseInt(width);
                        si.scaleImage(newWidth);
                        validate();
                        repaint();
                    }
                }
            });
        optionsMenu.add(resizeItem);

    }

    public static void main(String[] args)
    {
        JFrame iframe = new ImageViewerGUI();
        iframe.setVisible(true);
    }
}


class BaseFrame
    extends JFrame
{

    BaseFrame()
    {
        addWindowListener(new WindowAdapter()
            {
                public void windowClosing(WindowEvent e)
                {
                    System.exit(0);
                }
            });
        setSize(800, 500);
        setLocationRelativeTo(null);
    }

}


class ScaledImage
    extends JPanel
{
    private BufferedImage scaledImage;
    int width, height;

    public void setScaledImage(BufferedImage bufferedImage)
    {
        scaledImage = bufferedImage;
        width = scaledImage.getWidth();
        height = scaledImage.getHeight();
    }

    public BufferedImage getScaledImage()
    {
        return scaledImage;
    }

    public BufferedImage scaleImage(int newWidth)
    {
        int oldWidth = scaledImage.getWidth();
        int oldHeight = scaledImage.getHeight();
        int newHeight = (newWidth * oldHeight) / oldWidth;
        Image resizedImage = scaledImage.getScaledInstance(newWidth, newHeight, Image.SCALE_SMOOTH);

        // This code ensures that all the pixels in the image are loaded
        Image temp = new ImageIcon(resizedImage).getImage();

        // Create a buffered Image
        BufferedImage bufferedImage = new BufferedImage(temp.getWidth(null), temp.getHeight(null), BufferedImage.TYPE_INT_RGB);

        // Copy image to buffered image
        Graphics g = bufferedImage.getGraphics();

        // Clear background and paint the image
        g.setColor(Color.black);
        g.fillRect(0, 0, temp.getWidth(null), temp.getHeight(null));
        g.drawImage(temp, 0, 0, null);

        scaledImage = bufferedImage;
        return scaledImage;
    }

    protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        if (scaledImage != null) g.drawImage(scaledImage, 0, 0, this);
    }
}
 

innoc

Aktives Mitglied
Hallo SlaterB,

da gibt es doch einen Unterschied zwischen etwas lesen und etwas verstehen. Ich habe mir Deine vorherigen Vorschläge genau durchgelesen, aber scheinbar in letzter Konsequenz nicht verstanden. Ich denke, dass der Programmcode von Dir mir nun auf die Sprünge hilft. Auf jeden Fall danke ich Dir für deine konstruktive Kritik.
 

innoc

Aktives Mitglied
Nun gut, beide Versionen von SlaterB funktionieren hervorragend (an dieser Stelle nochmals: Vielen Dank an SlaterB). Bleibt nur das große Problem, dass das Bild sehr pixelig wird, wenn man das Bild mit dem Slider verkleinert und danach wieder vergrößert, was mich nicht verwundert und mir niemand hier zu erklären braucht. Das einzige, was mir hierzu einfällt, ist das BufferedImage vor dem Skalieren zu Serialisieren (dazu gibt es einen Artikel von Todd Greanier: Discover the secrets of the Java Serialization API) und nachdem mit dem Slider eine neue Weite und Höhe eingestellt wurde, das serialisierte Bild entsprechend zu skalieren. Entsprechend wäre meine Idee wie folgt:
Java:
import java.io.Serializable;

public class TransScaling implements Serializable, Runnable {
  transient private Thread transducer;

  public TransScaling() {
    startTransScaling();
  }

  public void run() {
    while (true) {
      // do transduction of scaling here
      // before moving the slider the image has to be streamed in its original resolution and rests as persistent copy during the whole time of program execution 
      // by stop moving the slider the streamed image with the original resolution has to be read and rescaled according to the specified width and height 
    }
  }

  private void writeObject(ObjectOutputStream out) throws IOException {
    out.defaultWriteObject();
  }

  private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
    in.defaultReadObject();
    startTransScaling();
  }

  private void startTransScaling() {
    transducer = new Thread(this);
    transducer.start();
  }

}

Weiters habe ich herausgefunden, daß man hierzu das Bild in einen ByteArray umwandeln muss und dann noch einen sog. PixelGrabber benötigt.
Meine Frage ans Forum:
Ist das realisierbar? Gibt es bessere Möglichkeiten?
 
S

SlaterB

Gast
wie zuvor geschrieben musst du meiner Ansicht nach einfach das Original NICHT überschreiben:
> scaledImage = bufferedImage;

behalte das Original in einer anderen Variable und verwende das immer mit dem aktuellen Slider-Wert, dann hast du immer das bestmögliche Ergebnis aus der Vorlage,
mit Serialiserung oder sonst was komischen hat das nichts zu tun
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
berserkerdq2 Warum soll ich shuffle nutzen, um bei Rückgabewert Collection eine Liste zurückzugeben? Java Basics - Anfänger-Themen 3
S Methoden Return Rückgabewert wird nicht übergeben Java Basics - Anfänger-Themen 8
B Rückgabewert boolean Java Basics - Anfänger-Themen 8
R Frage zu Methoden (Rückgabewert u. ohne.) Java Basics - Anfänger-Themen 2
H Array wird als Rückgabewert nicht akzeptiert? Java Basics - Anfänger-Themen 2
L Methoden Rückgabewert Verbergen / nicht mit ausgeben Java Basics - Anfänger-Themen 4
H Problem mit Rückgabewert Java Basics - Anfänger-Themen 7
R Boolean Methode Rückgabewert if() Java Basics - Anfänger-Themen 1
FelixN Array mit verschiedene Datentypen als Rückgabewert? (Long und Double) Java Basics - Anfänger-Themen 3
F Pascalsches Dreieck mit Rückgabewert Java Basics - Anfänger-Themen 2
D Dezimal zu Dual mit Rückgabewert Java Basics - Anfänger-Themen 39
Curtis_MC Methoden Rückgabewert von BiPredicate Java Basics - Anfänger-Themen 6
B Array als Rückgabewert in der Methode Java Basics - Anfänger-Themen 1
T Rückgabewert Problem Java Basics - Anfänger-Themen 2
A Methoden Rückgabewert Java Basics - Anfänger-Themen 6
I Referenz auf Klasse als Rückgabewert Java Basics - Anfänger-Themen 7
H Variablen Void und der Rückgabewert Java Basics - Anfänger-Themen 6
P Rückgabewert bestimmen Java Basics - Anfänger-Themen 17
J Warum wird Array durch Methode ohne Rückgabewert verändert? Java Basics - Anfänger-Themen 5
Tarrew Generics: Erste gemeinse Oberklasse als Rückgabewert Java Basics - Anfänger-Themen 1
I Rückgabewert einer Methode in anderer Klasse verwenden Java Basics - Anfänger-Themen 2
D for-Schleife Rückgabewert Java Basics - Anfänger-Themen 6
M Rückgabewert bei Methoden Java Basics - Anfänger-Themen 6
C Rückgabewert von Kontruktoren Java Basics - Anfänger-Themen 15
S Methoden Bei Liste als Rückgabewert: IndexOutOfBoundsException Java Basics - Anfänger-Themen 1
U Methoden Zugriff auf Array von weiterer Methode einer Klasse, Rückgabewert Problem Java Basics - Anfänger-Themen 5
O Was verursacht den Rückgabewert false bei der Methode ready() eines BufferedReaders Java Basics - Anfänger-Themen 9
K Methode ohne Rückgabewert in boolean Methode ändern Java Basics - Anfänger-Themen 6
S Methoden Rückgabewert einer Methode als Parameter an eine andere Methode übergeben, geht das? Java Basics - Anfänger-Themen 5
S Rückgabewert null in Methode mit Thread Java Basics - Anfänger-Themen 2
M Anstatt 1 int Rückgabewert, mehrere Rückgaben mit Arraylist Java Basics - Anfänger-Themen 8
N Klassen constructor Rückgabewert Java Basics - Anfänger-Themen 10
C Methoden Rückgabewert von statischer Methode ignorieren Java Basics - Anfänger-Themen 8
MiMa Methode mit Rückgabewert Java Basics - Anfänger-Themen 2
feardorcha Methodenaufruf Übergabe- und Rückgabewert Java Basics - Anfänger-Themen 5
T Variablen Rückgabewert aus einer Schleifen-Methode Java Basics - Anfänger-Themen 8
D Methode mit Rückgabewert Java Basics - Anfänger-Themen 5
K Rückgabewert einer Klassenmethode Java Basics - Anfänger-Themen 7
J Methoden mit und ohne Rückgabewert Java Basics - Anfänger-Themen 22
D Erste Schritte Als Rückgabewert Klasse Java Basics - Anfänger-Themen 5
D Rückgabewert Pixelgrabber Java Basics - Anfänger-Themen 3
S ArrayList und Rückgabewert Java Basics - Anfänger-Themen 2
T Methode - Rückgabewert Schreibweise Java Basics - Anfänger-Themen 6
S Interface Rückgabewert Java Basics - Anfänger-Themen 3
F if Anweisung mit Rückgabewert? Java Basics - Anfänger-Themen 4
B Methoden, Rückgabewert und Verknüpfungen Java Basics - Anfänger-Themen 15
V OOP Klassen Methoden Rückgabewert Java Basics - Anfänger-Themen 15
C Datentypen Rückgabewert von "new FileInputStream" Java Basics - Anfänger-Themen 4
S Datentypen String mit fester Länge (Rückgabewert einer Methode) Java Basics - Anfänger-Themen 2
O Rückgabewert mit unterschiedlichen Datentypen Java Basics - Anfänger-Themen 10
G List als Rückgabewert einer rekursiven Methode (Baum) Java Basics - Anfänger-Themen 3
T Array als Rückgabewert einer Methode Java Basics - Anfänger-Themen 3
A Rückgabewert ändert sich? Java Basics - Anfänger-Themen 9
C Thread mit Rückgabewert? Java Basics - Anfänger-Themen 4
S Rückgabewert einer Instanzvariable Java Basics - Anfänger-Themen 2
K rückgabewert combobox Java Basics - Anfänger-Themen 15
M Methoden mit Rückgabewert Java Basics - Anfänger-Themen 4
B Vector<Point> als Rückgabewert Java Basics - Anfänger-Themen 23
C Null als Rückgabewert Java Basics - Anfänger-Themen 7
O String[] Array als Rückgabewert Java Basics - Anfänger-Themen 7
G setValueAt Rückgabewert verarbeiten? Java Basics - Anfänger-Themen 12
P Methode mit 2 unterschiedlichem Rückgabewert Java Basics - Anfänger-Themen 10
L Prozess rückgabewert? Java Basics - Anfänger-Themen 5
I "Rückgabewert" von EditorFenster Java Basics - Anfänger-Themen 6
A ActionPerformed Methode ohne Rückgabewert Java Basics - Anfänger-Themen 12
G Rückgabewert bei JInternalFrame ? Java Basics - Anfänger-Themen 2
M Rückgabewert Java Basics - Anfänger-Themen 4
L Rückgabewert Java Basics - Anfänger-Themen 7
K Frage zu Rückgabewert List und ArrayList Java Basics - Anfänger-Themen 6
D Methode aufrufen funktioniert nicht ganz - Rückgabewert Bool Java Basics - Anfänger-Themen 12
M Rückgabewert einer Methode Java Basics - Anfänger-Themen 6
P Array als Rückgabewert Java Basics - Anfänger-Themen 4
halla Array an Methode übergeben / Array als Rückgabewert Java Basics - Anfänger-Themen 2
L Rückgabewert in Konstruktor? Java Basics - Anfänger-Themen 4
R Problem mit Rückgabewert Java Basics - Anfänger-Themen 5
M Null-Rückgabewert von Methoden = sauberes programmieren? Java Basics - Anfänger-Themen 3
D Rückgabewert einer Methode Java Basics - Anfänger-Themen 25
M JFileChooser Rückgabewert Java Basics - Anfänger-Themen 2
Niki_Tesla Rückgabewert Java Basics - Anfänger-Themen 2
A Hashtable als Rückgabewert Java Basics - Anfänger-Themen 3
A Methode mit Rückgabewert Java Basics - Anfänger-Themen 3
S JSlider und ChangeListener Java Basics - Anfänger-Themen 1
S OOP Zwei JSlider in einer Klasse Java Basics - Anfänger-Themen 2
Z JSlider - Text wird nich angezeigt Java Basics - Anfänger-Themen 0
S JSlider Schritt Größe Java Basics - Anfänger-Themen 5
F JSlider korrekt implementieren Java Basics - Anfänger-Themen 19
C Aktueller Wert von einem JSlider auf ein Label Java Basics - Anfänger-Themen 2
C JSlider und JRadioButton auf Label anzeigen? Java Basics - Anfänger-Themen 10
R Zeitachse mit JSlider Java Basics - Anfänger-Themen 13
V JSlider wird nicht angezeigt Java Basics - Anfänger-Themen 12
H Swing: JSlider wird nicht angezeigt Java Basics - Anfänger-Themen 5
G JSlider + Lautstärke Java Basics - Anfänger-Themen 10
S Graphic im Panel änder durch JSlider Java Basics - Anfänger-Themen 2
S Schieberegler (JSlider) funktioniert nicht Java Basics - Anfänger-Themen 5
K Farbenspiel mit dem jSlider Java Basics - Anfänger-Themen 5
? JSlider Java Basics - Anfänger-Themen 9
G JSlider Wert auslesen Java Basics - Anfänger-Themen 1
M ChangeListener Problem bei JSlider Java Basics - Anfänger-Themen 3
S undo auf JSlider Java Basics - Anfänger-Themen 9

Ähnliche Java Themen

Neue Themen


Oben