2013-06-09 6 views
5

Ich habe erhebliche Qualitätsverlust mit ImageIO.write, wie kann ich automatische Kompression deaktivieren?Qualitätsverlust mit ImageIO.write

val baos: ByteArrayOutputStream = new ByteArrayOutputStream 
val newBi = new BufferedImage(img.getWidth, img.getHeight, BufferedImage.TYPE_INT_RGB) 
val gr = newBi.createGraphics() 
gr.drawImage(img, 0, 0, img.getWidth(), img.getHeight(), Color.WHITE, null) 
ImageIO.write(newBi, "jpeg", baos) 
val b = baos.toByteArray 
baos.close() 

Antwort

9

Verwenden Sie ImageWriter.

ImageWriter writer = ImageIO.getImageWritersByFormatName("jpeg").next(); 
ImageWriteParam param = writer.getDefaultWriteParam(); 
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); // Needed see javadoc 
param.setCompressionQuality(1.0F); // Highest quality 
writer.write(image); 

Verwenden Sie für Nicht-Foto-Bilder .png.


Wie @PiotrekDe kommentiert, scheint das folgende mehr logisch.

writer.write(null, new IIOImage(image, null, null), param) 
+1

Ich habe diese Methoden ausprobiert, aber aus bestimmten Gründen ist das Ausgabebild mit Schwarz gefüllt. Weißt du, woher es kommen könnte? – Roch

+0

Sorry, ich wusste von diesen Methoden (und das Png ist langsam), aber im Allgemeinen pg. –

+2

Ich denke, Sie müssen "param" zurück zu "writer", wie: 'writer.write (null, neue IIOImage (Bild, null, null), param)' –

0

JPEG-Bilder verwenden verlustbehaftete Komprimierung. Verwenden Sie stattdessen png. Das ist auch komprimiert, aber mit einem verlustfreien Algorithmus.

1

In Scala, https://github.com/sksamuel/scrimage verwenden, können Sie die Komprimierungsstufe auf JPEG-Dateien eingestellt

val in = // some input stream or byte array 
val out = // some output stream etc 
Image(in).writer(Format.JPEG).withCompression(1.0).write(out) 

Sie einen beliebigen Wert zwischen 0 und 1,0 für die Komprimierungsstufe einstellen.

0

JPEG-Komprimierung ist verlustbehaftet. Aber PNG-Komprimierung ist verlustfrei. Also, ich schlage vor, im PNG-Format zu schreiben. Das bedeutet, dass Sie keine Qualitätsverluste erleiden, selbst wenn Sie im PNG-Format komprimieren. Einfache Linien:

ImageIO.write(newBI,"png",someOutputStream); 

Aber, wenn Sie es im jpg Format mit Qualität wünschen, stellen Sie Qualität zu 100% ein. Der folgende Code kann Ihnen helfen.

ImageWriter jpgWriter = ImageIO.getImageWritersByFormatName("jpg").next(); 
    ImageWriteParam jpgWriteParam = jpgWriter.getDefaultWriteParam(); 
    jpgWriteParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); 
    jpgWriteParam.setCompressionQuality(1f); 
    jpgWriter.setOutput(someOutputStream); 
    //better to use ImageOutputStream 
    jpgWriter.write(null,new IIOImage(yourImage, null, null), jpgWriteParam);