2013-08-29 5 views
7
  1. जावा/Grails में एक BufferedImage में फ़ाइल से छवियों को पढ़ने का सबसे तेज़ तरीका क्या है?
  2. BufferedImage से छवियों को जावा/Grails में एक फ़ाइल में लिखने का सबसे तेज़ तरीका क्या है?

मेरी संस्करण (पढ़ें):एक फ़ाइल से छवियों को पढ़ने/लिखने का सबसे तेज़ तरीका BufferedImage में?

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

मेरी संस्करण (लिख):

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() 

उत्तर

6

पढ़ने का आपका समाधान मूल रूप से बाइट्स को दो बार पढ़ रहा है, एक बार फ़ाइल से और एक बार ByteArrayInputStream से। कि

जावा 7 के साथ पढ़ने के लिए

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

जावा 7 के साथ

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

लिखने के Files.newInputStream करने के लिए कॉल एक ChannelInputStream जो (AFAIK) बफ़र नहीं है वापस आ जाएगी मत करो। आप रैप करने के लिए यह

new BufferedInputStream(Files.newInputStream(...)); 

तो कम आईओ कैसे आप इसका इस्तेमाल पर निर्भर करता है, डिस्क के लिए कॉल देखते हैं कि चाहता हूँ।

+0

मैंने पढ़ा है कि जावा टूलकिट पढ़ने के लिए बहुत तेज़ है, क्या यह सच नहीं है? यदि यह सच है तो क्या आप अपना जवाब संशोधित कर सकते हैं? –

+0

@ stephan1001 मुझे खेद है, मैं यूआई से संबंधित पैकेज से परिचित नहीं हूं। –

+0

फ़ाइलें और पथ का पूरा पैकेज क्या है? –

0

आप लेखन के लिए लगभग अच्छे हैं। बस इंटरमीडिएट ByteArrayOutputStream का उपयोग न करें। यह आपके कोड में एक विशाल बाधा है। इसके बजाए FileOutputStream को BufferedOutputStream में लपेटें और वही करें।

वही वास्तव में आपके पढ़ने के लिए चला जाता है। Itermediate ByteArrayInputStream निकालें।

5

मैं पार्टी के लिए देर हो रही है, लेकिन वैसे भी ...

वास्तव में, का उपयोग करते हुए:

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

और

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

... तेजी से साबित हो सकता है (यह कोशिश करते हैं, सुनिश्चित करने के लिए, एक प्रोफाइलर का उपयोग कर)।

इसका कारण यह है इन वेरिएंट RandomAccessFile समर्थित पर्दे के पीछे ImageInputStream/ImageOutputStream कार्यान्वयन, जबकि InputStream/OutputStream आधारित संस्करणों डिफ़ॉल्ट रूप से एक डिस्क समर्थित seekable धारा क्रियान्वयन का उपयोग करेगा का उपयोग करें। डिस्क-बैकिंग में स्ट्रीम की पूरी सामग्री को एक अस्थायी फ़ाइल में लिखना और संभवतः इससे वापस पढ़ना शामिल है (ऐसा इसलिए है क्योंकि छवि I/O अक्सर गैर-रैखिक डेटा पहुंच से लाभ प्राप्त करता है)।

आप धारा आधारित संस्करणों के साथ अतिरिक्त आई/ओ से बचने के लिए, और अधिक स्मृति का उपयोग करने की कीमत पर चाहते हैं, इसे कहते हैं अस्पष्ट ImageIO.setUseCache(false) नाम है, निष्क्रिय करने के लिए seekable इनपुट धाराओं के डिस्क कैशिंग संभव है। यदि आप बहुत बड़ी छवियों से निपट रहे हैं तो यह स्पष्ट रूप से एक अच्छा विचार नहीं है।

+0

तो यह संस्करण ImageIO.read (नई फ़ाइल (बेसपाथ + छवि स्रोत)); ImageIO.read से तेज है (नया BufferedInputStream (Files.newInputStream (Paths.get (बेसपाथ + छवि स्रोत))); क्या ये सच है? –

+1

@ stephan1001 सिद्धांत रूप में, हाँ ('उपयोग कैस' 'false' के लिए डिफ़ॉल्ट सेटिंग मानते हुए)। लेकिन जैसा कि मैंने कहा, सुनिश्चित करने के लिए उपाय करें। :-) – haraldK

+1

बस इसके बिल्ली के लिए, मैंने एक नमूना कार्यक्रम लिखा, जो फ़ाइल संस्करण, स्ट्रीम संस्करण और डिस्क कैश के बिना स्ट्रीम संस्करण का उपयोग करके एक मध्यम आकार का जेपीईजी 100 बार पढ़ता है। समय औसत समय है। फ़ाइल का उपयोग करने का समय: 36.76ms स्ट्रीम का उपयोग करने का समय: 40.32ms स्ट्रीम (उपयोग कैश == झूठा) का उपयोग करने का समय: 37.63ms ओएस एक्स, 2.66GHz i7 + SSD पर जेडीके 1.6.0_26-b03-383। आपका मिलेज भिन्न हो सकता है ... – haraldK

संबंधित मुद्दे