la sostituzione corretta per l'utilizzo del pacchetto com.sun.image.codec.jpeg interna Sun?
Domanda
Abbiamo qualche codice calci intorno che utilizza questo vecchio pacchetto interno Sun per manipolare immagini, essenzialmente codifica JPEG ad un formato e qualità specifica dopo lettura / decodifica da un InputStream. Esempi di codice di seguito. Gradirei una miglior esempio di sostituzione pratica utilizzando una corretta java. * O javax. * API.
private void encodeJPEG(BufferedImage bi, BufferedOutputStream out, float quality) throws
ImageFormatException, IOException {
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bi);
param.setQuality(quality, false);
param.setDensityUnit(DENSITY_UNIT);
param.setXDensity(DENSITY);
param.setYDensity(DENSITY);
encoder.setJPEGEncodeParam(param);
encoder.encode(bi);
}
private void initJPEG(File jpegFile) throws FileNotFoundException, IOException,
IOException {
FileInputStream inputStream = new FileInputStream(jpegFile);
try {
JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder(inputStream);
buffImage = decoder.decodeAsBufferedImage();
}
.....error handling.....
}
Soluzione
Non ho provato questo approccio, ma si può dare un'occhiata alla Immagine Java I / O API . Il JPEGImageWriteParam classe sarebbe di particolare interesse.
Altri suggerimenti
Ho avuto lo stesso problema, specie of.I ha fatto questo test, per misurare le differenze di codifica e scrivere su file con JpegCodec, ImageIO (senza parametri), ImageIO (con parametri).
int numTest = 200;
Robot robot = new Robot();
BufferedImage image = robot.createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()));
//JPEGCODEC
long t1 = System.currentTimeMillis();
ByteArrayOutputStream ba = new ByteArrayOutputStream();
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(ba);
JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(image);
param.setQuality(0.75f, false);
encoder.setJPEGEncodeParam(param);
File f = new File("TestJPEGCODEC");
f.mkdir();
for (int i = 0; i < numTest; i++) {
encoder.encode(image);
f = new File("TestJPEGCODEC\\test" + i + ".jpg");
FileOutputStream fo = new FileOutputStream(f);
fo.write(ba.toByteArray());
fo.flush();
ba.reset();
}
long t2 = System.currentTimeMillis();
System.out.println("JPEGCODEC");
System.out.println("Total time:: " + (t2 - t1) + " average time:: " + (t2 - t1) / numTest);
//NORMAL IMAGEIO
t1 = System.currentTimeMillis();
f = new File("TestImageIO");
f.mkdir();
for (int i = 0; i < numTest; i++) {
f = new File("TestImageIO\\test" + i + ".jpg");
ImageIO.write(image, "jpg", f);
}
t2 = System.currentTimeMillis();
System.out.println("ImageIO");
System.out.println("Total time:: " + (t2 - t1) + " average time:: " + (t2 - t1) / numTest);
Iterator<ImageWriter> it = ImageIO.getImageWritersByFormatName("jpg");
ImageWriter writer = null;
while (it.hasNext()) {
writer = it.next();
}
//IMAGEIO EXPLICIT MODE
t1 = System.currentTimeMillis();
ImageWriteParam par = writer.getDefaultWriteParam();
par.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
par.setCompressionQuality(0.75f);
f = new File("TestImageIOExplicity");
f.mkdir();
for (int i = 0; i < numTest; i++) {
f = new File("TestImageIOExplicity\\test" + i + ".jpg");
FileImageOutputStream output = new FileImageOutputStream(f);
writer.setOutput(output);
IIOImage img = new IIOImage(image, null, null);
writer.write(null, img, par);
output.close();
}
t2 = System.currentTimeMillis();
writer.dispose();
System.out.println("IMAGEIOPAR");
System.out.println("Total time:: " + (t2 - t1) + " average time:: " + (t2 - t1) / numTest);
Per il codice di cui sopra la mia prova risultato sono qui di seguito in ms.
JPEGCODEC
Total time:: 13750 average time:: 68
ImageIO
Total time:: 38906 average time:: 194
IMAGEIOPAR
Total time:: 43078 average time:: 215
So che should't uso il com.sun.image.codec.jpeg.JPEGCodec, ma con questo tipo di risultati, rende l'uso di ImageIO per la codifica / scrittura jpg unbearable.In mio progetto in corso la differenza medio codifica e scrittura è così grande che devo usare JPEGCODEC, oppure utilizzare un'altra libreria esterna per lo stesso effetto.