1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies. Weitere Informationen

Java - JPEG laden, verkleinern, speichern

Dieses Thema im Forum "Java" wurde erstellt von nils_eckert, 8. November 2004.

  1. nils_eckert

    nils_eckert Grünschnabel

    Hallo zusammen,

    wir müssen für die Uni ein Projekt machen, in dem wir unter anderem JPEGs verkleinern müssen (ne Galerie).

    Ich suche jetzt also ein Möglichkeit, wie z.B. bei der GD-Lib in PHP JPEGs mit Verschiedenen Qualitäten verkleinern zu können.

    Für alle Tips wäre ich dankbar.

    Viele Grüße,
    Nils
  2. Thomas Darimont

    Thomas Darimont Administrator

    Hallo!

    Schau mal hier:
    Code (Text):
    1.  
    2. package de.tutorials.test;
    3.  
    4. import java.awt.Graphics;
    5. import java.awt.Image;
    6. import java.awt.image.BufferedImage;
    7. import java.awt.image.RenderedImage;
    8. import java.io.File;
    9. import java.io.IOException;
    10.  
    11. import javax.imageio.ImageIO;
    12. import javax.swing.ImageIcon;
    13.  
    14. public class Test48 {
    15.  
    16.     public static void main(String[] args) {
    17.         try {
    18.             Image img = new ImageIcon(ImageIO.read(new File("c:/Beispiel.jpg")))
    19.                     .getImage();
    20.             System.out.println(img.getWidth(null));
    21.             System.out.println(img.getHeight(null));
    22.  
    23.             int wNew = 120, hNew = 90;
    24.  
    25.             Image scaledImage = img.getScaledInstance(wNew, hNew,
    26.                     Image.SCALE_SMOOTH);
    27.  
    28.             BufferedImage outImg = new BufferedImage(wNew, hNew,
    29.                     BufferedImage.TYPE_INT_RGB);
    30.             Graphics g = outImg.getGraphics();
    31.             g.drawImage(scaledImage, 0, 0, null);
    32.             g.dispose();
    33.  
    34.             ImageIO.write(outImg, "jpeg", new File("c:/Beispiel_small.jpg"));
    35.  
    36.         } catch (IOException e) {
    37.             e.printStackTrace();
    38.         }
    39.  
    40.     }
    41. }
    42.  
    43.  
    Schneller gehts wenn man das Image über graphics.drawImage(image,newWidth,newHeight,null) zeichnet...
    Siehe auch hier:
    http://www.tutorials.de/forum/java/...sser-graphics-drawimage-verwenden-sollte.html

    Gruß Tom
  3. nils_eckert

    nils_eckert Grünschnabel

    Wow, hätte nicht gedacht, dass das so einfach geht :)

    Ich liebe Java :)

    Vielen Dank für die schnelle Antwort
    Nils
  4. nils_eckert

    nils_eckert Grünschnabel

    Doppelposting :-(
  5. Billie

    Billie Erfahrenes Mitglied

    Hellas!

    Hab den Code von Thomas in meinem neuen Programm verwendet, das läuft inzwischen auch. Trotzdem kommt es mir vor, als könnten die verkleinerten und gespeicherten Bilder eine bessere Qualität haben. Gibt es hier evtl. Lösungsansätze? zB JPEG bietet doch verschiedene Qualitätstufen (0-100), kann man diese Ansprechen?

    lg Billie
  6. Thomas Darimont

    Thomas Darimont Administrator

    Hallo!

    Schau mal hier:
    Code (Text):
    1.  
    2. package de.tutorials;
    3.  
    4. import java.awt.image.BufferedImage;
    5. import java.io.File;
    6. import java.io.FileOutputStream;
    7.  
    8. import javax.imageio.ImageIO;
    9.  
    10. import com.sun.image.codec.jpeg.JPEGCodec;
    11. import com.sun.image.codec.jpeg.JPEGEncodeParam;
    12. import com.sun.image.codec.jpeg.JPEGImageEncoder;
    13.  
    14. public class JPEGCompressionExample {
    15.     /**
    16.      * @param args
    17.      */
    18.     public static void main(String[] args) throws Exception {
    19.         BufferedImage image = ImageIO.read(new File("c:/Wasserlilien.jpg"));
    20.  
    21.         JPEGImageEncoder jpegImageEncoder = JPEGCodec
    22.                 .createJPEGEncoder(new FileOutputStream(
    23.                         "c:/Wasserlilien_low.jpg"));
    24.         JPEGEncodeParam param = jpegImageEncoder
    25.                 .getDefaultJPEGEncodeParam(image);
    26.         param.setQuality(0.5F, true);
    27.         jpegImageEncoder.encode(image, param);
    28.     }
    29. }
    30.  
    31.  
    Gruß Tom
  7. Billie

    Billie Erfahrenes Mitglied

    Vielen Dank! Seh mir das bei Gelegenheit an, aber bin mir sicher, dass ich das verwenden kann.

    Nur noch eine andere, kleine Frage... warum gibt es standardmäßig keine Dokumentation zu den com.sun.* Klassen?! In diesen Klassen sind viele nützliche Dinge versteckt, aber woher soll man wissen, dass es sie gibt? Hatte das Problem schoneinmal mit Base64-De/Encoder ... gibt es in diesen Klassen auch schon.

    lg Billie
  8. Thomas Darimont

    Thomas Darimont Administrator

    Hallo!

    Die com.sun....* Klassen sind eigentlich auch nicht fuer den oeffentlichen Gebrauch gedacht... weiterhin ist nicht garantiert, dass diese Klassen auch bei anderen JVM Herstellern vorhanden sind.

    Hier eine Version ohne, com.sun....* Klassen:
    Code (Text):
    1.  
    2. package de.tutorials;
    3.  
    4. import java.awt.image.BufferedImage;
    5. import java.io.File;
    6. import java.util.Iterator;
    7. import java.util.Locale;
    8.  
    9. import javax.imageio.IIOImage;
    10. import javax.imageio.ImageIO;
    11. import javax.imageio.ImageWriter;
    12. import javax.imageio.plugins.jpeg.JPEGImageWriteParam;
    13.  
    14. public class JPEGCompressionExample {
    15.     /**
    16.      * @param args
    17.      */
    18.     public static void main(String[] args) throws Exception {
    19.         BufferedImage image = ImageIO.read(new File("c:/Winter_big.jpg"));
    20.         Iterator iterator = ImageIO.getImageWritersBySuffix("jpeg");
    21.         ImageWriter imageWriter = (ImageWriter) iterator.next();
    22.         JPEGImageWriteParam imageWriteParam = new JPEGImageWriteParam(Locale
    23.                 .getDefault());
    24.         imageWriteParam.setCompressionMode(JPEGImageWriteParam.MODE_EXPLICIT);
    25.         imageWriteParam.setCompressionQuality(0.5F);
    26.         IIOImage iioImage = new IIOImage(image, null, null);
    27.         imageWriter.setOutput(ImageIO.createImageOutputStream(new File(
    28.                 "c:/Winter_big_low.jpg")));
    29.         imageWriter.write(null, iioImage, imageWriteParam);
    30.     }
    31. }
    32.  
    Gruss Tom
  9. Billie

    Billie Erfahrenes Mitglied

    Neues Problem, mit dieser neuen Speicher-Methode bekomme ich keinen Output mehr auf meine Http-Verbindung.

    Also das funktioniert:

    Code (Text):
    1.  
    2. // fc = javax.jnlp.FileContents (JavaWebStart)
    3. imageWriter.setOutput(ImageIO.createImageOutputStream(fc[i].getOutputStream(true)));
    4.         imageWriter.write(null, iioImage, imageWriteParam);
    5.  
    Aber ich will die Datei ja nicht überschreiben, sondern an den Server über die Verbindung schiecken und das funktioniert nicht, obwohl die Verbindung steht (EchoServer meldet Verbindung hergestellt, verbindung wieder geschlossen).

    Code (Text):
    1.  
    2. ByteArrayOutputStream byteStream = new ByteArrayOutputStream(512);
    3.  
    4. imageWriter.setOutput(ImageIO.createImageOutputStream(byteStream));
    5. imageWriter.write(null, iioImage, imageWriteParam);
    6.  
    7. byteStream.writeTo(connection.getOutputStream());
    Oder auch...

    Code (Text):
    1.  
    2. HttpURLConnection connection = (HttpURLConnection) url.openConnection();
    3.  
    4. imageWriter.setOutput(ImageIO.createImageOutputStream(connection.getOutputStream()));
    5. imageWriter.write(null, iioImage, imageWriteParam);
    6.  
    Wo liegt hier der Hund begraben?
  10. Vl3sH

    Vl3sH Grünschnabel


    Guten Morgen!

    ich hab mal versucht dieses Programm bei mir zum Laufen zu kriegen. Ich benutze einen Javaeditor und habe auch meine Classpath und Path Pfade in die Umgebungsvariablen geschrieben. Doch ich kriege immer noch einen "java.lang.NoClassDefFoundError" Fehler. Kann mir jemand bei diesem Fehler weiterhelfen?

    Mfg
    Volker
  11. Moin!
    Wie rufst du denn das Programm auf und wo hast du es gespeichert?
    Da die Klasse sich in einem Paket befindet, muss sie auch entsprechend aufgerufen werden.
    Beispiel, die Klasse befindet sich in Verzeichnis "F:\examples\de\tutorials\test".
    Dann musst du in das Verzeichnis "F:\examples" wechseln und "java de.tutorials.test.Test48" aufrufen..


    *grüssle*
    MeinerEiner
  12. Vl3sH

    Vl3sH Grünschnabel

    Ja moin!

    C:\Dokumente und Einstellungen\Lego\Anwendungsdaten\JavaEditor\Test48.java

    Da liegt meine Datei. Ich rufe das Ganze wie gesagt über einen Java-Editor auf und der compiliert das Ganze auch direkt. Ich habe im Anhang eine Screenshot von dem Programm gemacht.

    Danke für eure Mühe

    Volker

    Anhänge:

    • Java.jpg
      Java.jpg
      Dateigröße:
      84,4 KB
      Aufrufe:
      1.415
  13. Vielleicht habe ich mich nicht deutlich genug ausgedrückt, aber die Paketstruktur eines Programms spiegelt sich direkt in der Dateistruktur wieder. Also, wenn das Programm sich im Paket de.tutorials.test befindet, muss es sich auch in einem Verzeichnis "\de\tutorials\test" befinden, ansonsten kommt es zu der dir beschrieben Exception!

    *grüssle*
    MeinerEiner
  14. Bäästy

    Bäästy Grünschnabel

    Hallo susammen,

    ich hab eine andere frage und zwar gib es eine Möglichkeit einen teil von einem bild auszuschneiden und zu speichern bzw ein bild erstellt das nur einen teil von dem ursprünglichen bild besitzt so dass man den rand weglässt ?
    so ähnlich wie die methode getScaledInstance. gibst da noch mehr in der richtung?

    wär cool ;-)
  15. nils_eckert

    nils_eckert Grünschnabel

    Hallo Bäästy,

    mit g.drawImage(...) zeichnest du ja das eingelesene und ggf. skalierte Bild auf das Zielbild.

    Dabei kannst du die Startkoordinate mitgeben, also die obere rechte Ecke in der begonnen werden soll, das Ursprungsbild auf das Zielbild zu übertragen.

    Sind diese Werte negativ, schneidest du oben und links ab. Sind die Werte größer als Null, hast du in deinem neu angelegten Bild oben und links einen Rahmen um das hinein kopierte.

    Code (Text):
    1. import java.awt.Graphics;
    2. import java.awt.Image;
    3. import java.awt.image.BufferedImage;
    4. import java.io.File;
    5. import java.io.IOException;
    6.  
    7. import javax.imageio.ImageIO;
    8. import javax.swing.ImageIcon;
    9.  
    10. public class Test {
    11.     public static void main(String[] args) throws IOException {
    12.         Image image = new ImageIcon("/Users/nilseckert/Desktop/test.jpg").getImage();
    13.  
    14.         int cutLeft = 50, cutTop = 500;
    15.         int width = 1024, height = 1024;
    16.  
    17.         BufferedImage targetImage = new BufferedImage(width, height, BufferedImage.SCALE_SMOOTH);
    18.  
    19.         Graphics g = targetImage.getGraphics();
    20.         g.drawImage(image, -cutLeft, -cutTop, null);
    21.         g.dispose();
    22.  
    23.         ImageIO.write(targetImage, "jpeg", new File("/Users/nilseckert/Desktop/test-cut.jpg"));
    24.     }
    25. }
    26.  
    Viele Grüße
    Nils
  16. Bäästy

    Bäästy Grünschnabel

    hey vielen dank
    das war genau das was ich gesucht hab danke
    java 4 ever
  17. hannovergeist

    hannovergeist Grünschnabel

    vielen dank für den code.

Diese Seite empfehlen