So erhalten Sie ein qualitativ hochwertiges Thumbnail
Ich versuche zu erstellen hochwertige Miniatur dieses Bild, mit Java und Scalr 3.2
Dies ist der relevante source code, wo THUMB_WIDTH = 77
und THUMB_HEIGHT = 57
BufferedImage srcImg = ImageIO.read(new File(sourceFile));
BufferedImage dstImg = Scalr.resize(srcImg, Scalr.Method.QUALITY,
THUMB_WIDTH, THUMB_HEIGHT);
ImageIO.write(dstImg, format, new File(destFile));
Wenn ich format = "png"
, hier ist das Ergebnis:
Wenn ich format = "jpg"
, hier ist das Ergebnis:
Mit imagemagick identifizieren ich habe herausgefunden, dass die JPEG-Datei wird gespeichert mit einer Qualität von 75, ist völlig unzureichend, um erstellen Sie eine gut aussehende Miniatur. Das PNG sieht nicht so gut zu mir.
Hier ist die Ausgabe identifizieren der original-Datei und die zwei miniaturen:
$ identify 42486_1.jpg 42486_s1.jpg 42486_s1.png
42486_1.jpg JPEG 580x435 580x435+0+0 8-bit DirectClass 50.6KB 0.000u 0:00.000
42486_s1.jpg[1] JPEG 77x58 77x58+0+0 8-bit DirectClass 2.22KB 0.000u 0:00.000
42486_s1.png[2] PNG 77x58 77x58+0+0 8-bit DirectClass 12.2KB 0.000u 0:00.000
Fragen
- Wie die Verbesserung der Qualität der generierten thumbnail?
- So speichern Sie ein JPEG-Bild mit höherer Qualität? Ich möchte versuchen, mit höherer Qualität und die Ergebnisse vergleichen. Ich konnte nicht finden, dass irgendetwas in der JavaDoc für ImageIO.schreiben.
- Warum ich sagen, Scalr, dass meine maximale Abmessungen sind 77x57 und-Ausgang ein Bild 77x58? Ich denke, dass ist die Wahrung der Proportionen, aber das sind meine maximale Breite und maximale Höhe. Breite oder Höhe könnte weniger sein aber nicht mehr.
UPDATE: Mit einer Suche im web fand ich einen Artikel darüber, wie passen Sie die JPEG-Bildkomprimierung Qualität. Ich schrieb meine eigene Methode zum speichern eines BufferedImage Einstellung der Qualität:
/**
* Write a JPEG file setting the compression quality.
*
* @param image
* a BufferedImage to be saved
* @param destFile
* destination file (absolute or relative path)
* @param quality
* a float between 0 and 1, where 1 means uncompressed.
* @throws IOException
* in case of problems writing the file
*/
private void writeJpeg(BufferedImage image, String destFile, float quality)
throws IOException {
ImageWriter writer = null;
FileImageOutputStream output = null;
try {
writer = ImageIO.getImageWritersByFormatName("jpeg").next();
ImageWriteParam param = writer.getDefaultWriteParam();
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
param.setCompressionQuality(quality);
output = new FileImageOutputStream(new File(destFile));
writer.setOutput(output);
IIOImage iioImage = new IIOImage(image, null, null);
writer.write(null, iioImage, param);
} catch (IOException ex) {
throw ex;
} finally {
if (writer != null) writer.dispose();
if (output != null) output.close();
}
}
Hier sind die Ergebnisse. PNG:
JPEG-Qualität 75:
JPEG-Qualität 90 (die gravatars auf stackoverflow gespeichert werden als JPEG-Qualität 90):
und die filesize:
thumb90.jpg JPEG 77x58 77x58+0+0 8-bit DirectClass 6.89KB 0.000u 0:00.000
UPDATE 2: test zum Vergleich Scalr mit java-Bild-Skalierung.
private void scaleAndSaveImageWithScalr(String sourceFile, String destFile, int width, int height)
throws IOException {
BufferedImage sourceImage = ImageIO.read(new File(sourceFile));
BufferedImage destImage = Scalr.resize(sourceImage, Scalr.Method.QUALITY, width, height);
writeJpeg(destImage, destFile, JPEG_QUALITY);
}
private void scaleAndSaveImageWithJImage(String sourceFile, String destFile, int width, int height)
throws IOException {
BufferedImage sourceImage = ImageIO.read(new File(sourceFile));
ResampleOp resampleOp = new ResampleOp(width, height);
resampleOp.setFilter(ResampleFilters.getLanczos3Filter());
resampleOp.setUnsharpenMask(AdvancedResizeOp.UnsharpenMask.Normal);
BufferedImage destImage = resampleOp.filter(sourceImage, null);
writeJpeg(destImage, destFile, JPEG_QUALITY);
}
JPEG-Qualität 90 erzeugt mit Scalr:
JPEG-Qualität 90 erzeugt mit java-Bild-Skalierung:
Habe ich nicht erhalten keine weitere Rückmeldung, also mein persönliches Fazit ist, dass die java-Bild-Skalierung bietet eine überragende Qualität, und so ist es der Bibliothek, die ich wähle.
writeJpeg()
aufrufen muss writer.dispose()
und ausgegeben.close()
in endlich
- block zur Freigabe dieser Ressourcen! InformationsquelleAutor der Frage stivlo | 2011-10-12
Du musst angemeldet sein, um einen Kommentar abzugeben.
Dies ist keine vollständige Antwort auf deine Frage, aber:
Über die JPEG-Qualität:
Komprimierung kann die Qualität eingestellt werden, mit einem
ImageWriteParam
als hier beschrieben. Sie empfehlen die Verwendung vonint
Wert von 0/1 aber ich glaube, das sollten Sie wirklich geben Sie einen float-Wert zwischen 0.0 und 1.0.In Bezug auf Ihre Skalierung dimension Fragen:
Aus der Scalr homepage:
In Ihrem Fall die primäre dimension wird eine Breite von 77 und somit mit einer Höhe von 57 werden ignoriert.
InformationsquelleAutor der Antwort teabot
@Stivlo, ich bin leider nicht zu beantworten, ich habe nie eine Benachrichtigung von SO zu der Frage stellen.
java-Bild-Skalierung hat einige nette Filter helfen, die mit der fine-tuning, wenn Sie es brauchen. Das heißt, in v4.2 imgscalr ich fügte hinzu, die neue ULTRA_QUALITY , vielleicht bekommen Sie näher an, was Sie wollen.
Ich hoffe, das hilft, aber dies zu realisieren ist, wird beantwortet, fast ein Jahr nach der Tat, leider. Tut mir Leid, dass.
InformationsquelleAutor der Antwort Riyad Kalla
Habe ich die gleichen tests und java-Bild-Skalierung definitiv bessere Ergebnisse für die Vorschaubilder kleiner als 250px. Es unterstützt auch die scharfen Filterung, welche die Ergebnisse besser.
Ich halte beide Bibliotheken, da die syntax von Scalr ist oft einfacher, mit nur einer Zeile.
InformationsquelleAutor der Antwort Rafael Sanches
Beachten Sie, dass wenn Ihr Bilder haben einen alpha-Kanal, die beide Bibliotheken sind problematisch. Ich bin nur sprechen über das verkleinern der Bilder, habe ich noch nicht getestet vergrößern.
java-image-scaling kann eine hässliche Rand um die transparenten Kanten, je nach Bild, und das sieht sehr schlecht. Ich fand keine Möglichkeit, dies zu vermeiden.
Scalr ist nur problematisch mit den (ultra) - Qualität der Modi. Es kann leicht verwendet werden, in einer Weise, die funktioniert gut, aber: die bikubische interpolation Blätter Artefakte in transparenten Bildern, so möchten Sie vielleicht, es zu vermeiden. Da es der Standard für (ultra -) Qualität der Bilder, und scaleImageIncrementally() geschützt ist, müsste man eine Unterklasse für dieses, obwohl, wenn Sie wollen, dass die Qualität (ein Bruchteil höher als 2 sieht sehr verschwommen mit der bilinearen Filterung, obwohl).
InformationsquelleAutor der Antwort Axel Dörfler
Wenn Sie möchten hohen Qualität des Ergebnisses, so verwenden Sie [RapidDecoder][1] - Bibliothek. Es ist einfach wie folgt:
import rapid.- decoder.BitmapDecoder;
...
Bitmap bitmap = BitmapDecoder.aus(getResources(), R. drawable.Bild)
.Skalierung(Breite, Höhe)
.useBuiltInDecoder(true)
.decode();
Vergessen Sie nicht, verwenden eingebauten decoder, wenn Sie wollen, zu skalieren weniger als 50% und ein HQ-Ergebnis.
InformationsquelleAutor der Antwort S.M.Mousavi