Java ImageIO; mal lahm, mal flott

15/01/2016 - 20:08 von Peter | Report spam
Hallo,

hier habe ich eine große Menge jpeg-Images (ca. 3k), von denen ich für
die Weiterverarbeitung ihre Größe benötige.
Der Helfer in allen Lebenslagen heißt stackoverflow, und da findet sich
folgende viel versprechende Lösung:

http://stackoverflow.com/questions/...using-java

"Here is something very simple and handy.

BufferedImage bimg = ImageIO.read(new File(filename));
int width = bimg.getWidth();
int height = bimg.getHeight();"

Funktioniert tatsàchlich; hat nur einen schweren Nachteil:
Diese "Löschung" dauert eeeeeehhhhhhhhwig!
Ca. 10 Sekunden für ein Image!

Ich habe nàmlich nicht nur viele Images, sie sind auch recht groß (8k x
8k); insgesamt ca. 50GB.

Wiedermal eine OO-Sternstunde: Es wird ein 10 Tonnen schweres Objekt
instanziiert, nur um es dann nach seine Größe zu fragen :-(

Aber wenn man bei obiger Website etwas nach unten scrollt, findet man
noch einen Vorschlag:

/**
* Gets image dimensions for given file
* @param imgFile image file
* @return dimensions of image
* @throws IOException if the file is not a known image
*/
public static Dimension getImageDimension(File imgFile) throws IOException {
int pos = imgFile.getName().lastIndexOf(".");
if (pos == -1)
throw new IOException("No extension for file: " +
imgFile.getAbsolutePath());
String suffix = imgFile.getName().substring(pos + 1);
Iterator<ImageReader> iter = ImageIO.getImageReadersBySuffix(suffix);
if (iter.hasNext()) {
ImageReader reader = iter.next();
try {
ImageInputStream stream = new FileImageInputStream(imgFile);
reader.setInput(stream);
int width = reader.getWidth(reader.getMinIndex());
int height = reader.getHeight(reader.getMinIndex());
return new Dimension(width, height);
} catch (IOException e) {
log.warn("Error reading: " + imgFile.getAbsolutePath(), e);
} finally {
reader.dispose();
}
}

throw new IOException("Not a known image file: " +
imgFile.getAbsolutePath());
}

Und siehe da, alles flutscht quasi in Nullzeit.

Noch weiter unten hat sich jemand gefunden, der die Performanz der
verschiedenen Ansàtze miteinander verglichen hat; da lernt man, dass die
durchaus um den Faktor 200(!) auseinander liegen.

Vielleicht ist das auch der Grund, warum der Geoserver so grottenlahm ist...
 

Lesen sie die antworten

#1 Thomas Richter
21/01/2016 - 10:40 | Warnen spam
On 15.01.2016 20:08, Peter wrote:
Hallo,

"Here is something very simple and handy.

BufferedImage bimg = ImageIO.read(new File(filename));
int width = bimg.getWidth();
int height = bimg.getHeight();"

Funktioniert tatsàchlich; hat nur einen schweren Nachteil:
Diese "Löschung" dauert eeeeeehhhhhhhhwig!
Ca. 10 Sekunden für ein Image!

Ich habe nàmlich nicht nur viele Images, sie sind auch recht groß (8k x
8k); insgesamt ca. 50GB.

Wiedermal eine OO-Sternstunde: Es wird ein 10 Tonnen schweres Objekt
instanziiert, nur um es dann nach seine Größe zu fragen :-(

Aber wenn man bei obiger Website etwas nach unten scrollt, findet man
noch einen Vorschlag:

/**
* Gets image dimensions for given file
* @param imgFile image file
* @return dimensions of image
* @throws IOException if the file is not a known image
*/
public static Dimension getImageDimension(File imgFile) throws IOException {
int pos = imgFile.getName().lastIndexOf(".");
if (pos == -1)
throw new IOException("No extension for file: " +
imgFile.getAbsolutePath());
String suffix = imgFile.getName().substring(pos + 1);
Iterator<ImageReader> iter = ImageIO.getImageReadersBySuffix(suffix);
if (iter.hasNext()) {
ImageReader reader = iter.next();
try {
ImageInputStream stream = new FileImageInputStream(imgFile);
reader.setInput(stream);
int width = reader.getWidth(reader.getMinIndex());
int height = reader.getHeight(reader.getMinIndex());
return new Dimension(width, height);
} catch (IOException e) {
log.warn("Error reading: " + imgFile.getAbsolutePath(), e);
} finally {
reader.dispose();
}
}

throw new IOException("Not a known image file: " +
imgFile.getAbsolutePath());
}

Und siehe da, alles flutscht quasi in Nullzeit.



Der Unterschied zwischen beiden Lösungen ist, dass die erstere Lösung
das Bild vollstàndig decodiert, wàhrend die zweite nur den Header
abfragt. Kann man, sofern JPEG gesetzt ist, auch problemlos "von Hand"
erledigen. Die Bildgröße steht im SOF-Marker, der im Binàrstrom durch
die Bytefolge 0xff 0xc0 gekennzeichnet ist. Einfach da rausziehen und
gut ist...

Grüße,
Thomas

Ähnliche fragen