Discussion:
Java ImageIO; mal lahm, mal flott
(zu alt für eine Antwort)
Peter
2016-01-15 19:08:13 UTC
Permalink
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/672916/how-to-get-image-height-and-width-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...
Thomas Richter
2016-01-21 09:40:38 UTC
Permalink
Post by Peter
Hallo,
"Here is something very simple and handy.
BufferedImage bimg = ImageIO.read(new File(filename));
int width = bimg.getWidth();
int height = bimg.getHeight();"
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
/**
* Gets image dimensions for given file
*/
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

Lesen Sie weiter auf narkive:
Loading...