Da Sie nach einer Bibliothek gefragt haben, lautet die eigentliche Antwort hier: stackoverflow.com/questions/244164/… . Es ist viel einfacher zu verwenden als der Code in der akzeptierten Antwort;)
Artur Gajowy
Ich bin mit dem Bibliotheksteil nicht einverstanden: Graphics2D ist Teil der awt-Bibliothek und Open Source. Für den letzten Teil (Open Source) bin ich mir nicht 100% sicher, aber wer würde sich den awt-Code überhaupt ansehen?
Prüfen Sie mit der MethodeerveAlpha die falsche Richtung (für den Bildtyp)?
Thilo
Ich stimme @morgancodes zu. Die Bildqualität ist viel schlechter als bei OS X Preview, wenn Sie die Größe auf die gleichen Abmessungen ändern. Ich werde einige Open-Source-Bibliotheken ausprobieren, um festzustellen, ob sie besser abschneiden.
Thilo
1
"Ich werde einige Open-Source-Bibliotheken ausprobieren, um zu sehen, ob sie besser abschneiden." +1 für imgscalr aus der Antwort von @ RiyadKalla.
Thilo
182
FWIW Ich habe gerade (Apache 2, gehostet auf GitHub) eine einfache Bildskalierungsbibliothek für Java namens imgscalr veröffentlicht (verfügbar in Maven Central ).
Die Bibliothek implementiert einige verschiedene Ansätze zur Bildskalierung (einschließlich des inkrementellen Ansatzes von Chris Campbell mit einigen geringfügigen Verbesserungen) und wählt entweder den für Sie optimalen Ansatz aus, wenn Sie dazu aufgefordert werden, oder bietet Ihnen den schnellsten oder am besten aussehenden Ansatz (wenn Sie dies wünschen) danach fragen).
Die Verwendung ist kinderleicht, nur eine Reihe statischer Methoden. Der einfachste Anwendungsfall ist:
Bei allen Vorgängen werden die ursprünglichen Proportionen des Bildes beibehalten. In diesem Fall fordern Sie imgscalr auf, die Größe Ihres Bilds innerhalb von 200 Pixel Breite und 200 Pixel Höhe zu ändern. Standardmäßig wird automatisch der am besten aussehende und schnellste Ansatz ausgewählt, da dies nicht der Fall war nicht angegeben.
Am Anfang war mir klar, dass dies wie Eigenwerbung aussieht (es ist), aber ich verbrachte meinen Teil der Zeit damit, genau dasselbe Thema zu googeln und kam immer wieder auf unterschiedliche Ergebnisse / Ansätze / Gedanken / Vorschläge und beschloss, mich hinzusetzen und eine zu schreiben einfache Implementierung, die 80-85% der Anwendungsfälle anspricht, in denen Sie ein Bild haben und wahrscheinlich ein Miniaturbild dafür möchten - entweder so schnell wie möglich oder so gut wie möglich (für diejenigen, die es versucht haben, werden Sie feststellen Wenn Sie ein Graphics.drawImage auch mit BICUBIC-Interpolation auf ein ausreichend kleines Bild ausführen, sieht es immer noch wie Müll aus.
Riad, ich habe Scalr gern benutzt. Ich bin gespannt, wie Sie zu einer API mit allen statischen Methoden gekommen sind. Ich hatte eine ähnliche API geschrieben, die einem Baumeister näher kam. Wie new ImageScaler(img).resizeTo(...).rotate(...).cropTo(...).toOutputBuffer(). Ich mag deinen Weg auch und ich denke, es ist einfacher.
Amir Raminfar
4
Amir, das Builder-Muster funktioniert auch wunderbar für diese Arten von Bibliotheken. Ich habe mich zufällig für den Ansatz der statischen Methode entschieden, weil ich dachte, es sei für neue Benutzer einfacher, dem Haar zu folgen, und für das Verwendungsmuster, das ich von imgscalr (ursprünglich) erwartet hatte Nur einzelne Größenänderungsmethoden) profitierten nicht von einem Instanzhaltestatus (der Builder-Instanz). Also habe ich die Objektinstanziierung gespeichert und mich für die statischen Methoden entschieden. Ich habe mich an jeder Stelle, an der ich dies vermeiden kann, entschieden gegen die Schaffung von Objekten innerhalb von imgscalr ausgesprochen. Beide Ansätze funktionieren jedoch hervorragend.
Riyad Kalla
5
+1 für die Bereitstellung im zentralen Maven-Repository!
Grilse
Was ist diese BufferedImage-Klasse? Warum findet Android Studio sie nicht? @Riyad Kalla
Milad
3
@ xe4me BufferedImage ist eine Klasse im J2SE JDK (Teil des Java2D-Frameworks), die zur Darstellung unkomprimierter Pixeldaten verwendet wird. Es ist nicht für Android verfügbar. Android bietet eigene Klassen für die Arbeit mit Bilddaten.
Riyad Kalla
54
Thumbnailator ist eine Open-Source-Bibliothek zur Größenänderung von Bildern für Java mit einer fließenden Oberfläche, die unter der MIT-Lizenz vertrieben wird.
Ich habe diese Bibliothek geschrieben, weil es überraschend schwierig sein kann, hochwertige Miniaturansichten in Java zu erstellen, und der resultierende Code ziemlich chaotisch sein kann. Mit Thumbnailator ist es möglich, ziemlich komplizierte Aufgaben mit einer einfachen fließenden API auszudrücken.
Ein einfaches Beispiel
Ein einfaches Beispiel: Nehmen Sie ein Bild und ändern Sie die Größe auf 100 x 100 (wobei das Seitenverhältnis des Originalbilds beibehalten wird) und speichern Sie es in einer Datei in einer einzigen Anweisung:
Diese Bibliothek verwendet auch die progressive bilineare Skalierungsmethode , die in Filthy Rich Clients von Chet Haase und Romain Guy hervorgehoben wurde, um hochwertige Miniaturansichten zu generieren und gleichzeitig eine akzeptable Laufzeitleistung sicherzustellen.
Chris 'Artikel hat mich genau dazu motiviert, imgscalr zu schreiben. und Fragen wie diese (und Antworten wie Ihre). Viele Leute fragen immer und immer wieder, wie man gut aussehende Thumbnails von einem Bild bekommt. Es gibt eine Reihe von Möglichkeiten, Chris's ist nicht immer der beste Weg, es hängt davon ab, was Sie versuchen und wie groß die Reduzierung ist. imgscalr spricht all das an und es ist 1 Klasse.
Riyad Kalla
2
+1, ich stimme zu, Filthy Rich-Kunden sind eines der besten Java-Bücher auf dem Markt von "Effective Java", aber ImgScalr verwende ich, weil ich faul bin.
Wenn Sie mit großen Bildern arbeiten oder ein gut aussehendes Ergebnis erzielen möchten, ist dies in Java keine triviale Aufgabe. Wenn Sie dies einfach über eine Rescale-Operation über Graphics2D tun, wird keine hochwertige Miniaturansicht erstellt. Sie können dies mit JAI tun, aber es erfordert mehr Arbeit, als Sie sich vorstellen können, um etwas zu erhalten, das gut aussieht, und JAI hat die böse Angewohnheit, Ihre JVM mit OutOfMemory-Fehlern zu belasten.
Ich schlage vor, ImageMagick als externe ausführbare Datei zu verwenden, wenn Sie damit durchkommen können. Es ist einfach zu bedienen und macht den Job richtig, so dass Sie nicht müssen.
Wenn es möglich ist, imagemagick auf Ihrer Maschine zu installieren, empfehle ich im4java . Es ist eine sehr dünne Abstraktionsschicht auf der Befehlszeilenschnittstelle, macht aber ihre Arbeit sehr gut.
Es ist auch auf GitHub ( github.com/mortennobel/java-image-scaling.git ) verfügbar und hat derzeit Version 8.7. Es musste in pom.xml behoben werden (Änderung von Quelle und Ziel auf mindestens 1.6, da neuere Maven 1.5 nicht mehr unterstützen).
Image Magick wurde erwähnt. Es gibt ein JNI-Frontend-Projekt namens JMagick. Es ist kein besonders stabiles Projekt (und Image Magick selbst hat sich bekanntermaßen stark verändert und sogar die Kompatibilität beeinträchtigt). Wir haben jedoch gute Erfahrungen mit JMagick und einer kompatiblen Version von Image Magick in einer Produktionsumgebung gemacht, um die Skalierung mit hohem Durchsatz und geringer Latenz durchzuführen. Die Geschwindigkeit war wesentlich besser als bei einer Java-Grafikbibliothek, die wir zuvor ausprobiert haben.
Sie können den Wert auch auf BICUBIC setzen. Dies führt zu einer besseren Bildqualität, ist jedoch teurer. Es gibt andere Rendering-Hinweise, die Sie festlegen können, aber ich habe festgestellt, dass die Interpolation den bemerkenswertesten Effekt erzeugt. Denken Sie daran, wenn Sie viel zoomen möchten, wird Java-Code höchstwahrscheinlich sehr langsam sein. Ich finde, dass größere Bilder eine Verzögerung von etwa 300% Zoom erzeugen, selbst wenn alle Rendering-Hinweise so eingestellt sind, dass die Geschwindigkeit über die Qualität optimiert wird.
Es stellt sich heraus, dass das Schreiben eines performanten Skalierers nicht trivial ist. Ich habe es einmal für ein Open Source-Projekt gemacht: ImageScaler .
Im Prinzip würde 'java.awt.Image # getScaledInstance (int, int, int)' auch die Arbeit erledigen, aber es gibt einen bösen Fehler dabei - siehe meinen Link für Details.
Ich habe eine Lösung mit den frei verfügbaren Klassen (AnimatedGifEncoder, GifDecoder und LWZEncoder) entwickelt, die für die Verarbeitung von GIF-Animationen verfügbar sind.
Sie können das jgifcode jar herunterladen und die GifImageUtil-Klasse ausführen. Link: http://www.jgifcode.com
Wenn Sie imgScalr nicht importieren möchten, wie die Antwort von @Riyad Kalla, über der ich auch getestet habe, funktioniert dies einwandfrei. Sie können dies jedoch aus der Antwort von Peter Walser @Peter Walser zu einem anderen Problem machen:
/**
* utility method to get an icon from the resources of this class
* @param name the name of the icon
* @return the icon, or null if the icon wasn't found.
*/publicIcon getIcon(String name){Icon icon =null;
URL url =null;ImageIcon imgicon =null;BufferedImage scaledImage =null;try{
url = getClass().getResource(name);
icon =newImageIcon(url);if(icon ==null){System.out.println("Couldn't find "+ url);}BufferedImage bi =newBufferedImage(
icon.getIconWidth(),
icon.getIconHeight(),BufferedImage.TYPE_INT_RGB);Graphics g = bi.createGraphics();// paint the Icon to the BufferedImage.
icon.paintIcon(null, g,0,0);
g.dispose();
bi = resizeImage(bi,30,30);
scaledImage = bi;// or replace with this line Scalr.resize(bi, 30,30);
imgicon =newImageIcon(scaledImage);}catch(Exception e){System.out.println("Couldn't find "+ getClass().getName()+"/"+ name);
e.printStackTrace();}return imgicon;}publicstaticBufferedImage resizeImage (BufferedImage image,int areaWidth,int areaHeight){float scaleX =(float) areaWidth / image.getWidth();float scaleY =(float) areaHeight / image.getHeight();float scale =Math.min(scaleX, scaleY);int w =Math.round(image.getWidth()* scale);int h =Math.round(image.getHeight()* scale);int type = image.getTransparency()==Transparency.OPAQUE ?BufferedImage.TYPE_INT_RGB :BufferedImage.TYPE_INT_ARGB;boolean scaleDown = scale <1;if(scaleDown){// multi-pass bilinear div 2int currentW = image.getWidth();int currentH = image.getHeight();BufferedImage resized = image;while(currentW > w || currentH > h){
currentW =Math.max(w, currentW /2);
currentH =Math.max(h, currentH /2);BufferedImage temp =newBufferedImage(currentW, currentH, type);Graphics2D g2 = temp.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2.drawImage(resized,0,0, currentW, currentH,null);
g2.dispose();
resized = temp;}return resized;}else{Object hint = scale >2?RenderingHints.VALUE_INTERPOLATION_BICUBIC :RenderingHints.VALUE_INTERPOLATION_BILINEAR;BufferedImage resized =newBufferedImage(w, h,BufferedImage.TYPE_INT_ARGB);Graphics2D g2 = resized.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
g2.drawImage(image,0,0, w, h,null);
g2.dispose();return resized;}}
Antworten:
Nach dem Laden des Bildes können Sie versuchen:
quelle
FWIW Ich habe gerade (Apache 2, gehostet auf GitHub) eine einfache Bildskalierungsbibliothek für Java namens imgscalr veröffentlicht (verfügbar in Maven Central ).
Die Bibliothek implementiert einige verschiedene Ansätze zur Bildskalierung (einschließlich des inkrementellen Ansatzes von Chris Campbell mit einigen geringfügigen Verbesserungen) und wählt entweder den für Sie optimalen Ansatz aus, wenn Sie dazu aufgefordert werden, oder bietet Ihnen den schnellsten oder am besten aussehenden Ansatz (wenn Sie dies wünschen) danach fragen).
Die Verwendung ist kinderleicht, nur eine Reihe statischer Methoden. Der einfachste Anwendungsfall ist:
Bei allen Vorgängen werden die ursprünglichen Proportionen des Bildes beibehalten. In diesem Fall fordern Sie imgscalr auf, die Größe Ihres Bilds innerhalb von 200 Pixel Breite und 200 Pixel Höhe zu ändern. Standardmäßig wird automatisch der am besten aussehende und schnellste Ansatz ausgewählt, da dies nicht der Fall war nicht angegeben.
Am Anfang war mir klar, dass dies wie Eigenwerbung aussieht (es ist), aber ich verbrachte meinen Teil der Zeit damit, genau dasselbe Thema zu googeln und kam immer wieder auf unterschiedliche Ergebnisse / Ansätze / Gedanken / Vorschläge und beschloss, mich hinzusetzen und eine zu schreiben einfache Implementierung, die 80-85% der Anwendungsfälle anspricht, in denen Sie ein Bild haben und wahrscheinlich ein Miniaturbild dafür möchten - entweder so schnell wie möglich oder so gut wie möglich (für diejenigen, die es versucht haben, werden Sie feststellen Wenn Sie ein Graphics.drawImage auch mit BICUBIC-Interpolation auf ein ausreichend kleines Bild ausführen, sieht es immer noch wie Müll aus.
quelle
new ImageScaler(img).resizeTo(...).rotate(...).cropTo(...).toOutputBuffer()
. Ich mag deinen Weg auch und ich denke, es ist einfacher.Thumbnailator ist eine Open-Source-Bibliothek zur Größenänderung von Bildern für Java mit einer fließenden Oberfläche, die unter der MIT-Lizenz vertrieben wird.
Ich habe diese Bibliothek geschrieben, weil es überraschend schwierig sein kann, hochwertige Miniaturansichten in Java zu erstellen, und der resultierende Code ziemlich chaotisch sein kann. Mit Thumbnailator ist es möglich, ziemlich komplizierte Aufgaben mit einer einfachen fließenden API auszudrücken.
Ein einfaches Beispiel
Ein einfaches Beispiel: Nehmen Sie ein Bild und ändern Sie die Größe auf 100 x 100 (wobei das Seitenverhältnis des Originalbilds beibehalten wird) und speichern Sie es in einer Datei in einer einzigen Anweisung:
Ein fortgeschrittenes Beispiel
Das Ausführen komplexer Größenänderungsaufgaben wird durch die fließende Benutzeroberfläche von Thumbnailator vereinfacht.
Nehmen wir an, wir möchten Folgendes tun:
0.85
,thumbnail.
an den Anfang angehängtIn Thumbnailator übersetzt, könnten wir die oben genannten Schritte wie folgt ausführen:
Ein Hinweis zur Bildqualität und -geschwindigkeit
Diese Bibliothek verwendet auch die progressive bilineare Skalierungsmethode , die in Filthy Rich Clients von Chet Haase und Romain Guy hervorgehoben wurde, um hochwertige Miniaturansichten zu generieren und gleichzeitig eine akzeptable Laufzeitleistung sicherzustellen.
quelle
Sie benötigen dazu keine Bibliothek. Sie können es mit Java selbst tun.
Chris Campbell hat eine ausgezeichnete und detaillierte Beschreibung der Skalierung von Bildern - siehe diesen Artikel .
Chet Haase und Romain Guy haben in ihrem Buch Filthy Rich Clients auch eine detaillierte und sehr informative Beschreibung der Bildskalierung .
quelle
Java Advanced Imaging ist jetzt Open Source und bietet die erforderlichen Vorgänge.
quelle
Wenn Sie mit großen Bildern arbeiten oder ein gut aussehendes Ergebnis erzielen möchten, ist dies in Java keine triviale Aufgabe. Wenn Sie dies einfach über eine Rescale-Operation über Graphics2D tun, wird keine hochwertige Miniaturansicht erstellt. Sie können dies mit JAI tun, aber es erfordert mehr Arbeit, als Sie sich vorstellen können, um etwas zu erhalten, das gut aussieht, und JAI hat die böse Angewohnheit, Ihre JVM mit OutOfMemory-Fehlern zu belasten.
Ich schlage vor, ImageMagick als externe ausführbare Datei zu verwenden, wenn Sie damit durchkommen können. Es ist einfach zu bedienen und macht den Job richtig, so dass Sie nicht müssen.
quelle
Wenn es möglich ist, imagemagick auf Ihrer Maschine zu installieren, empfehle ich im4java . Es ist eine sehr dünne Abstraktionsschicht auf der Befehlszeilenschnittstelle, macht aber ihre Arbeit sehr gut.
quelle
Die Java-API bietet keine Standard-Skalierungsfunktion für Bilder und eine Herabstufung der Bildqualität.
Aus diesem Grund habe ich versucht, cvResize von JavaCV aus zu verwenden, aber es scheint Probleme zu verursachen.
Ich habe eine gute Bibliothek für die Bildskalierung gefunden: Fügen Sie einfach die Abhängigkeit für "Java-Bildskalierung" in Ihre pom.xml ein.
Im Maven-Repository erhalten Sie dazu die aktuelle Version.
Ex. In Ihrem Java-Programm
quelle
Sie können versuchen, das GraphicsMagick-Bildverarbeitungssystem mit im4java als Befehlszeilenschnittstelle für Java zu verwenden.
GraphicsMagick bietet viele Vorteile, aber einen für alle:
quelle
Image Magick wurde erwähnt. Es gibt ein JNI-Frontend-Projekt namens JMagick. Es ist kein besonders stabiles Projekt (und Image Magick selbst hat sich bekanntermaßen stark verändert und sogar die Kompatibilität beeinträchtigt). Wir haben jedoch gute Erfahrungen mit JMagick und einer kompatiblen Version von Image Magick in einer Produktionsumgebung gemacht, um die Skalierung mit hohem Durchsatz und geringer Latenz durchzuführen. Die Geschwindigkeit war wesentlich besser als bei einer Java-Grafikbibliothek, die wir zuvor ausprobiert haben.
http://www.jmagick.org/index.html
quelle
Verwenden Sie einfach die Antwort von Burkhard, aber fügen Sie diese Zeile nach dem Erstellen der Grafiken hinzu:
Sie können den Wert auch auf BICUBIC setzen. Dies führt zu einer besseren Bildqualität, ist jedoch teurer. Es gibt andere Rendering-Hinweise, die Sie festlegen können, aber ich habe festgestellt, dass die Interpolation den bemerkenswertesten Effekt erzeugt. Denken Sie daran, wenn Sie viel zoomen möchten, wird Java-Code höchstwahrscheinlich sehr langsam sein. Ich finde, dass größere Bilder eine Verzögerung von etwa 300% Zoom erzeugen, selbst wenn alle Rendering-Hinweise so eingestellt sind, dass die Geschwindigkeit über die Qualität optimiert wird.
quelle
Sie können Marvin (reines Java-Bildverarbeitungsframework) für diese Art von Operation verwenden: http://marvinproject.sourceforge.net
Skalierungs-Plug-In: http://marvinproject.sourceforge.net/en/plugins/scale.html
quelle
Es stellt sich heraus, dass das Schreiben eines performanten Skalierers nicht trivial ist. Ich habe es einmal für ein Open Source-Projekt gemacht: ImageScaler .
Im Prinzip würde 'java.awt.Image # getScaledInstance (int, int, int)' auch die Arbeit erledigen, aber es gibt einen bösen Fehler dabei - siehe meinen Link für Details.
quelle
Ich habe eine Lösung mit den frei verfügbaren Klassen (AnimatedGifEncoder, GifDecoder und LWZEncoder) entwickelt, die für die Verarbeitung von GIF-Animationen verfügbar sind.
Sie können das jgifcode jar herunterladen und die GifImageUtil-Klasse ausführen. Link: http://www.jgifcode.com
quelle
Sie können folgendes beliebtes Produkt verwenden: thumbnailator
quelle
Wenn Sie imgScalr nicht importieren möchten, wie die Antwort von @Riyad Kalla, über der ich auch getestet habe, funktioniert dies einwandfrei. Sie können dies jedoch aus der Antwort von Peter Walser @Peter Walser zu einem anderen Problem machen:
quelle
Versuchen Sie diese folgende Methode:
quelle