JPG Qualität mit JPEGImageEncoder auf 100% stellen

Dario3000

Mitglied
Hallo zusammen,
ich bin PHP/JS Entwickler und habe von Java so gut wie Null Ahnung.

Ich habe nun ein fertiges Script welches Bilder aus der Zwischenablage direkt in eine Webseite einbindet.
Leider ist die Qualität der Bilder nicht besonders gut (Ich tippe auf ca. 90% Qualität)

Meine Frage wäre nun, ob mir jemand sagen kann, wie ich in diesem Code die JPEG Qualität auf 100% setze,
oder alternativ das Ausgabeformat auf .PNG stelle.
Beides wäre ok.



Java:
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.Toolkit;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
import javax.swing.JApplet;
import javax.swing.JOptionPane;
import javax.swing.ImageIcon;
import java.io.ByteArrayOutputStream;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import com.sun.image.codec.jpeg.JPEGCodec;
import java.net.URL;
import java.net.URLConnection;
import java.io.InputStream;
import javax.swing.JLabel;

public class PasteImageApplet extends JApplet{

    Clipboard clipboard;
    Toolkit toolkit;
	JLabel lbl;

    public String getClipboardImageURL(String server){
		lbl.setText("pasting image");

        String url = "";
        try{
            DataFlavor dataFlavor = DataFlavor.imageFlavor;
            System.out.println(dataFlavor.getDefaultRepresentationClass());
            Object object  = null;

            try{
                object = clipboard.getContents(null).getTransferData(dataFlavor);
            }catch (Exception e){
                JOptionPane.showMessageDialog(null, "No image found.");
                return "";
            }

            BufferedImage img = (BufferedImage) object;

            BufferedImage bimg = null;
            int w = img.getWidth(null);
            int h = img.getHeight(null);
            bimg = new BufferedImage(w,h,BufferedImage.TYPE_INT_RGB);


            ImageIcon ii = new ImageIcon(img);
            ImageObserver is = ii.getImageObserver();

            bimg.getGraphics().setColor(new Color(255, 255, 255));
            bimg.getGraphics().fillRect(0, 0, w, h);
            bimg.getGraphics().drawImage(ii.getImage(), 0, 0, is);

            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            JPEGImageEncoder jpeg = JPEGCodec.createJPEGEncoder(stream);
            jpeg.encode(bimg);                                               

            URL u = new URL(server);
            URLConnection con = u.openConnection();
            //String boundary = "-----------------------------7d637a1aa100de";
            con.setDoOutput(true);
            con.getOutputStream().write(stream.toByteArray());
            /*con.getOutputStream().write(((String)
                    "--"+boundary+"\r\n "+
                    "Content-Disposition: form-data; name=\"img\"; filename=\"filename\"\r\n"+
                    "Content-Type: image/jpeg\r\n "+
                    "Content-Transfer-Encoding: base64\r\n\r\n" +
                    Base64.encodeBytes(stream.toByteArray())).getBytes());*/
            con.connect();
            InputStream inputStream = con.getInputStream();
            byte [] urlBytes = new byte [inputStream.available()];
            inputStream.read(urlBytes);
            url = new String(urlBytes);
            System.out.print(url);
	        lbl.setText("image pasted");
        } catch (Exception exc){
	        lbl.setText("an error occurred: " + exc.getMessage());
            /*if (ShowExceptions.ShowExceptions)
                exc.printStackTrace();*/
        }
        return url;
    }

    public void init() {
		lbl = new JLabel("");
		lbl.setText("applet started");
		add(lbl);
        toolkit = Toolkit.getDefaultToolkit();
        clipboard = toolkit.getSystemClipboard();
    }
}


In vielen anderen Sprachen setzt man beim Resampling oder beim Generierten des Bildes einfach den gewünschten Prozentwert hinzu.
Ich kann mir vorstellen, dass es in Java vergleichbar einfach ist, nur muss man das natürlich wissen.

Ich danke schon mal
 

Kruemel

Mitglied
Habe jetzt den Code nicht genau gelesen aber warum verwendest du nicht ImageIO? Kannst damit auch direkt aus einem Stream schreiben und das Dateiformat angeben.

Gruß, Kruemel
 

Dario3000

Mitglied
OK danke,
ich seh' schon, ich werde mich mehr mit dem Thema beschäftigen müssen.
Im Moment versteh ich noch nicht einmal die Syntax, da tu ich mich dann mit paar Codeschnipseln natürlich sehr schwer :)
 

Marco13

Top Contributor
Nee, ist nicht so aufwändig ... irgendwo hier im Forum hatte ich den Snippet schonmal gepostet: Damit kann man ein BufferedImage mit einer gegebenen Qualität in einen gegebenen OutputStream schreiben:
Java:
public static void writeJPG(
    BufferedImage bufferedImage, 
    OutputStream outputStream, 
    float quality) throws IOException
{
    Iterator<ImageWriter> iterator = 
        ImageIO.getImageWritersByFormatName("jpg");
    ImageWriter imageWriter = iterator.next();
    ImageWriteParam imageWriteParam = imageWriter.getDefaultWriteParam();
    imageWriteParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
    imageWriteParam.setCompressionQuality(quality);
    ImageOutputStream imageOutputStream = 
        new MemoryCacheImageOutputStream(outputStream);
    imageWriter.setOutput(imageOutputStream);
    IIOImage iioimage = new IIOImage(bufferedImage, null, null);
    imageWriter.write(null, iioimage, imageWriteParam);
    imageOutputStream.flush();
}

Ja, zugegeben: Es IST kompliziert - zumindest denke ich, dass es praktisch "unmöglich" (d.h. nicht praktikabel) ist, sich das durch Lesen der API zu erschließen. Aber so als Utility-Funktion passt das ja vielleicht.
 

Dario3000

Mitglied
Danke Marco. Kann ich das einfach in meine Funktion einbauen, oder muss ich etwas Spezielles dabei beachten.
Wie gesagt, von Java habe ich keine Ahnung.

Das obere Script wird über eine Seite geöffnet, holt sich das Bild aus der Zwischenablage und gibt das generierte JPEG an eine PHP Funktion weiter, welche das Bild dann auf dem Server ablegt und im Browser öffnet. Das funktioniert alles, nur das mit der JPEG Qualität im Java Code habe ich nicht hinbekommen/verstanden.
 

Marco13

Top Contributor
Nö, einfach einfügen. Entweder die Methode (imports werden von der IDE automatisch behandelt) oder als Utility-Klasse...
Java:
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Iterator;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageOutputStream;
import javax.imageio.stream.MemoryCacheImageOutputStream;

public class JPGWrite 
{
	public static void writeJPG(
	    BufferedImage bufferedImage, 
	    OutputStream outputStream, 
	    float quality) throws IOException
	{
	    Iterator<ImageWriter> iterator = 
	        ImageIO.getImageWritersByFormatName("jpg");
	    ImageWriter imageWriter = iterator.next();
	    ImageWriteParam imageWriteParam = imageWriter.getDefaultWriteParam();
	    imageWriteParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
	    imageWriteParam.setCompressionQuality(quality);
	    ImageOutputStream imageOutputStream = 
	        new MemoryCacheImageOutputStream(outputStream);
	    imageWriter.setOutput(imageOutputStream);
	    IIOImage iioimage = new IIOImage(bufferedImage, null, null);
	    imageWriter.write(null, iioimage, imageWriteParam);
	    imageOutputStream.flush();
	}
}
Ist in der Form jetzt ungetestet, aber sollte im Prinzip so funktionieren.
 

Dario3000

Mitglied
Vielen Dank für die Hilfe Marco,
nur leider kann ich dir nicht sagen ob es klappt, da das gesamte Script heute bei mir nicht mehr funktioniert.

Selbst auf der Demoseite des Herstellers (Clipboard image demo) konnte ich gestern ganz normal mit der "Druck" Taste und einem Klick auf "Paste it" meinen Screenshot anzeigen lassen. Heute klappt es noch nicht einmal dort.

Java ist auf dem neusten Stand und vom Browser wird auch nichts unterdrückt.
Gestern gings in FF, Chrome, Opera und Safari. Heute geht's in keinem der Browser.
Einzig die Java Konsole gibt mir "class java.io.InputStream" aus, aber das war gestern so viel ich weiß auch schon.

Ich versteh das nicht...
Irgendwie werd ich mich damit wohl nicht anfreunden können :)

Trotzdem dir vielen Dank für die Hilfsbereitschaft. Sollte ich es jemals zum Laufen bekommen, melde ich mich.
 

Dario3000

Mitglied
Nein leider nicht, "class java.io.InputStream" ist die einzige Meldung. Taucht jedes Mal auf, wenn ich auf den Button klicke.

Ich kann mit "v" den "Thread-Stack" in der Console ausgeben
aber das hat, wie ich sehe, nichts mit dem Aplet zu tun, sondern sind lokale Einstellungen.

Ich poste es mal, sieht nicht so aus, als wenn persönlich Daten drin wären.
Sorry vorab fürs Spamen :)

Java:
wieder gelöscht, damit keine Verwirrung entsteht 26.04.2011 - 22:57 Uhr
 
Zuletzt bearbeitet:

Dario3000

Mitglied
Ach halt, wenn ich meine Trace-Stufe erhöhe, kommt doch einiges mehr raus:

den Code von vorher lösche ich wieder, führt sonst nur zur Verwirrung


Java:
basic: Applet wird angehalten...
basic: Fortschritts-Listener entfernt: sun.plugin.util.GrayBoxPainter$GrayBoxProgressListener@1b994de
basic: Applet wird zerstört...
basic: Applet wird verworfen...
basic: Applet-Thread wird beigetreten...
basic: Applet-Thread wurde beigetreten...
basic: Informationen werden gesucht...
basic: ClassLoader wird freigegeben: sun.plugin.ClassLoaderInfo@297ffb, refcount=0
basic: ClassLoader wird im Cache abgelegt: sun.plugin.ClassLoaderInfo@297ffb
basic: Aktuelle Größe des ClassLoader-Cache: 2
basic: Fertig...
basic: Applet wird beendet...
basic: ClassLoader wird referenziert: sun.plugin.ClassLoaderInfo@297ffb, refcount=1
basic: Fortschritts-Listener hinzugefügt: sun.plugin.util.GrayBoxPainter$GrayBoxProgressListener@11a4bd4
basic: Applet wird geladen...
basic: Applet wird initialisiert...
basic: Applet wird gestartet...
basic: completed perf rollup
java.net.MalformedURLException: no protocol: 
	at java.net.URL.<init>(Unknown Source)
	at java.net.URL.<init>(Unknown Source)
	at java.net.URL.<init>(Unknown Source)
	at sun.plugin.liveconnect.SecureInvocation.checkLiveConnectCaller(Unknown Source)
	at sun.plugin.liveconnect.SecureInvocation.access$000(Unknown Source)
	at sun.plugin.liveconnect.SecureInvocation$2.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at sun.plugin.liveconnect.SecureInvocation.CallMethod(Unknown Source)
liveconnect: JavaScript: Standard-Sicherheitsrichtlinie = 
liveconnect: JavaScript: Java-Systemcode wird aufgerufen
liveconnect: JavaScript: Standard-Sicherheitsrichtlinie = 
liveconnect: JavaScript: Java-Systemcode wird aufgerufen
liveconnect: JavaScript: Standard-Sicherheitsrichtlinie = 
liveconnect: JavaScript: Java-Systemcode wird aufgerufen

... DAS WIEDERHOLT SICH DANN NOCH PAAR HUNDERT MAL ...

liveconnect: JavaScript: Java-Systemcode wird aufgerufen
liveconnect: JavaScript: Standard-Sicherheitsrichtlinie = 
class java.io.InputStream
liveconnect: JavaScript: Java-Systemcode wird aufgerufen
liveconnect: JavaScript: Standard-Sicherheitsrichtlinie = 
class java.io.InputStream
network: Verbindung von [url]http://lassebunk.dk/demos/clipboard-image/shoot.php[/url] mit Proxy=DIRECT wird hergestellt

Sieht für mich nach einer Schleife aus, aber wieso hat es dann gestern funktioniert?
 

Marco13

Top Contributor
Hm... bei solchen Sachen (URLs, Connections, Security und JavaScript) kenn' ich mich auch nicht so aus ... aber ... hast du die URL geändert, oder irgendwelche Sicherheitseinstellungen?
"java.net.MalformedURLException: no protocol:"
kommt eigentlich, wenn man versucht, aus einem Applet auf eine Datei zuzugreifen, aber dabei den Pfad nicht richtig angibt... Versuchst du denn irgendwo auf lokale Dateien zuzugreifen?
Vielleicht kann da jemand anderes noch mehr Informationen oder Ideen rausziehen...
 

Dario3000

Mitglied
Nein an der URL habe ich nichts geändert. Wie gesagt, selbst die Demo auf der Herstellerseite funktioniert es nicht mehr bei mir.
An den Sicherheitseinstellungen habe ich auch nicht rumgeschraubt. Ich wüsste noch nicht einmal, wo ich mir die anzeigen lassen kann. Das Zertifikat habe ich bestätigt und ich finde es auch in der Liste meiner Zertifikate. Merkwürdig...
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
Shadowrunner Variablen Gibt es eine Möglichkeit die Ziffern/Stellen einer Zahl fest zu legen? Java Basics - Anfänger-Themen 3
T Java FXML selbes Fenster verschiedene Stellen im Programm Java Basics - Anfänger-Themen 5
M Wie lassen sich Konstanten in Bedingung stellen? Java Basics - Anfänger-Themen 1
C alle möglichen Kombinationen zweier Ziffern auf drei / vier / und 'n" Stellen Java Basics - Anfänger-Themen 11
Z Char Array an zufälligen stellen mit einem "x" füllen. Java Basics - Anfänger-Themen 4
J PdfTable Spalte höher stellen Java Basics - Anfänger-Themen 2
J Datei auslesen (nur bestimmte Stellen) Java Basics - Anfänger-Themen 2
I Scanner auf 10 Stellen begrenzt? Java Basics - Anfänger-Themen 5
Y Konkrete Hilfe gesucht - Anzahl der Stellen einer eingegebenen Zahl überprüfen Java Basics - Anfänger-Themen 5
F Erste Schritte Binär zahle auf 8 stellen aufüllen Java Basics - Anfänger-Themen 2
J Wo kann man Fragen zu ireport stellen. Java Basics - Anfänger-Themen 0
E jProgressBar auf 0 stellen Java Basics - Anfänger-Themen 1
B Methoden JaveEditor - Wie kann ich Methodenbeschreibung zur Verfügung stellen Java Basics - Anfänger-Themen 1
M 2 Stellen in einem Array vergleichen und bei übereinstimmen eine davon ersetzen Java Basics - Anfänger-Themen 1
S programm speichern und fertig stellen Java Basics - Anfänger-Themen 2
Z OOP Objekte einer Klasse weiteren Klassen zur Verfügung stellen Java Basics - Anfänger-Themen 17
C Int mit vorangestellten Nullen und maximal 4 stellen erzeugen. Java Basics - Anfänger-Themen 4
M Vergleich zweier Array Stellen mit equals/NullpointerException Java Basics - Anfänger-Themen 9
B String auslesen und Stellen im Array speichern Java Basics - Anfänger-Themen 1
A Rekursion, Anzahl von Stellen ausgeben Java Basics - Anfänger-Themen 7
O Java Interfaces für andere Programmiersprachen zur Verfuegung stellen? Java Basics - Anfänger-Themen 2
I Texte an bestimmten Stellen ausgeben. Java Basics - Anfänger-Themen 3
M Programm fertig stellen, Jar mit Bildern Java Basics - Anfänger-Themen 14
T Sting -> Array, leere Stellen löschen Java Basics - Anfänger-Themen 6
B Datentypen Wurzel auf n stellen nach dem Komma selber zeihen -> double zu schlecht Java Basics - Anfänger-Themen 19
F Signifikante Stellen einschränken Java Basics - Anfänger-Themen 9
R Bestimmte Stellen eines BigInteger Java Basics - Anfänger-Themen 7
V Bestimmte Stellen aus .txt Datei auslesen Java Basics - Anfänger-Themen 11
H Zahl auf 2 nachkomma stellen runden Java Basics - Anfänger-Themen 13
F Preis auf eine Nachkomma stellen aufrunden Java Basics - Anfänger-Themen 8
N Datentypen Double nach 2 stellen kürzen Java Basics - Anfänger-Themen 4
T System.out.printf Zeilenumbruch nach x Stellen Java Basics - Anfänger-Themen 4
S compiler auf 6.0 stellen Java Basics - Anfänger-Themen 6
Z Anzahl der Stellen nach dem Komma verändern. Java Basics - Anfänger-Themen 7
M String an bestimmten Stellen zerlegen Java Basics - Anfänger-Themen 12
C DecimalFormat-Patern funktioniert ab 11 Stellen nicht mehr Java Basics - Anfänger-Themen 3
D Datentypen Double 2 stellen hinter dem Komma ausgeben OHNE decimalformat Java Basics - Anfänger-Themen 2
R Stellen einer Variable auslesen Java Basics - Anfänger-Themen 4
-horn- Runden auf x-Stellen wirklich nur so umständlich? Java Basics - Anfänger-Themen 9
F Vierstellige Zahl eingeben und an 4 stellen eines Arrays ausgeben Java Basics - Anfänger-Themen 3
N Doulbe - 2 Stellen nach dem Komma Java Basics - Anfänger-Themen 9
B Kommazahl mit 2 Nachkomma-Stellen im jFormattedTextField Java Basics - Anfänger-Themen 6
S Zufallszahl mit 6 Stellen erzeugen Java Basics - Anfänger-Themen 4
O Applet ins Netz stellen Java Basics - Anfänger-Themen 6
G DoubleWert immer mit 2 stellen nach dem Komma? Java Basics - Anfänger-Themen 13
Y Programm im Hintergrund stellen Java Basics - Anfänger-Themen 5
D String mit 2 Stellen nach dem Komma (Dezimalzahl) Java Basics - Anfänger-Themen 9
B Stellen nach dem Komma Java Basics - Anfänger-Themen 2
P Integer Anzahl der Stellen Java Basics - Anfänger-Themen 4
S Wie runden man noch mal auf bestimmte stellen? Java Basics - Anfänger-Themen 8
F bei einem Float nur x Stellen nach dem Komma anzeigen ? Java Basics - Anfänger-Themen 7
M Eclipse: Einfärbung ändern für angeklickte Stellen im Source Java Basics - Anfänger-Themen 5
M Float-Zahl auf x Stellen beschränken Java Basics - Anfänger-Themen 6
P Dezimalstellen limitieren (runden auf 2 Stellen) Java Basics - Anfänger-Themen 3
S bei Integer mehr stellen als nötig ausgeben - 0006 Java Basics - Anfänger-Themen 5
C Länge/Anzahl der Stellen eines Integers Java Basics - Anfänger-Themen 8
J Textauslesen, an bestimmten stellen? Java Basics - Anfänger-Themen 20
D Double auf 2 stellen nach dem Komma reduzieren.. Java Basics - Anfänger-Themen 7

Ähnliche Java Themen

Neue Themen


Oben