2013-08-29 7 views
7
  1. Was ist der schnellste Weg, Bilder von einer Datei in ein BufferedImage in Java/Grails zu lesen?
  2. Was ist der schnellste Weg, Bilder von einem BufferedImage in eine Datei in Java/Grails zu schreiben?

meine Variante (lesen):Schnellste Möglichkeit zum Lesen/Schreiben von Bildern aus einer Datei in ein BufferedImage?

byte [] imageByteArray = new File(basePath+imageSource).readBytes() 
InputStream inStream = new ByteArrayInputStream(imageByteArray) 
BufferedImage bufferedImage = ImageIO.read(inStream) 

meine Variante (schreiben):

BufferedImage bufferedImage = // some image 
def fullPath = // image page + file name 
byte [] currentImage 

try{ 

    ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
    ImageIO.write(bufferedImage, "jpg", baos); 
    baos.flush(); 
    currentImage = baos.toByteArray(); 
    baos.close(); 

    }catch(IOException e){ 
     System.out.println(e.getMessage()); 
    }  
    }  


def newFile = new FileOutputStream(fullPath) 
newFile.write(currentImage) 
newFile.close() 

Antwort

6

Ihre Lösung zu lesen ist grundsätzlich Lesen der Bytes zweimal, einmal aus der Datei und einmal aus der ByteArrayInputStream. Tun Sie das nicht, dass

Mit Java 7

BufferedImage bufferedImage = ImageIO.read(Files.newInputStream(Paths.get(basePath + imageSource))); 

Mit Java 7 lesen

ImageIO.write(bufferedImage, "jpg", Files.newOutputStream(Paths.get(fullPath))); 

Der Aufruf von Files.newInputStream zu schreiben, wird eine ChannelInputStream zurück, die (AFAIK) nicht gepuffert. Sie möchten es einwickeln

So dass es weniger IO-Aufrufe auf der Festplatte gibt, je nachdem, wie Sie es verwenden.

+0

Ich lese, dass Java Toolkit ist sehr schnell zum Lesen ist das nicht wahr? Kannst du deine Antwort ändern, wenn das wahr ist? –

+0

@ stephan1001 Es tut mir leid, ich kenne keine UI-bezogenen Pakete. –

+0

Was ist das vollständige Paket von Dateien und Pfaden? –

0

Sie sind fast gut für das Schreiben. Verwenden Sie nicht das Zwischenprodukt ByteArrayOutputStream. Es ist ein riesiger Engpass in Ihrem Code. Wickeln Sie den FileOutputStream stattdessen in einen BufferedOutputStream und führen Sie das gleiche aus.

Das gleiche gilt in der Tat für Ihre Lesung. Entfernen Sie das Intermediate ByteArrayInputStream.

5

Ich bin spät zur Party, aber trotzdem ...

Eigentlich mit:

ImageIO.read(new File(basePath + imageSource)); 

und

ImageIO.write(bufferedImage, "jpeg", new File(fullPath)); 

... vielleicht schneller beweisen (versuchen Sie es, mit einem Profiler, um sicherzustellen, dass).

Dies liegt daran, diese Varianten verwenden RandomAccessFile -backed ImageInputStream/ImageOutputStream Implementierungen hinter den Kulissen, während die InputStream/OutputStream basierten Versionen standardmäßig eine Datenträger-backed seekable Stream Implementierung verwenden. Die Datenträgerunterstützung umfasst das Schreiben des gesamten Inhalts des Streams in eine temporäre Datei und möglicherweise das Zurücklesen von diesem (da Bild-I/O häufig von nichtlinearem Datenzugriff profitiert).

Wenn Sie zusätzliche I/O mit den Strom basierten Versionen vermeiden wollen, auf Kosten von mehr Speicher verwenden, ist es möglich, die zweideutig ImageIO.setUseCache(false), mit dem Namen zu nennen Disk-Caching der seekable Eingangsströme abzuschalten. Dies ist offensichtlich keine gute Idee, wenn Sie mit sehr großen Bildern zu tun haben.

+0

So diese Version ImageIO.read (neue Datei (BasePath + ImageSource)); ist schneller als ImageIO.read (neuer BufferedInputStream (Files.newInputStream (Paths.get (basePath + imageSource)))); Ist das wahr? –

+1

@ stephan1001 Theoretisch, ja (vorausgesetzt, die Standardeinstellung für 'useCahce' 'false'). Aber wie gesagt, messen Sie um sicher zu sein. :-) – haraldK

+1

Nur zum Spaß habe ich ein Beispielprogramm geschrieben, das 100 mal ein mittelgroßes JPEG mit der Dateiversion, der Stream-Version und der Stream-Version ohne Disk-Cache liest. Zeiten sind Durchschnittszeiten. Zeit mit Datei: 36.76ms Zeit mit Stream: 40.32ms Zeit mit Stream (useCache == false): 37.63ms JDK 1.6.0_26-b03-383 auf OS X, 2.66GHz i7 + SSD. Ihr Kilometerstand kann variieren ... – haraldK