2013-08-27 2 views
5

में बहुत बड़ी छवि फ़ाइल से क्षेत्र पढ़ें, क्या जावा लाइब्रेरी है जो पूरी छवि को स्मृति में रखे बिना बहुत बड़ी छवि (जैसे जेपीईजी) फ़ाइलों (> 10,000 x 10,000 पिक्सेल) के क्षेत्रों को पढ़ सकती है।जावा

या वैकल्पिक रूप से, जो जावा लाइब्रेरी कम ओवरहेड के साथ बहुत बड़ी छवि फ़ाइलों को संभालने में सक्षम है।

+0

क्या आप बाइट ऑफसेट और लंबाई या पूरी छवि से कुछ पिक्सल के मामले में एक क्षेत्र पढ़ना चाहते हैं? –

+0

पिक्सेल के मामले में एक क्षेत्र। – f3lix

+0

ठीक है, मैंने नीचे पोस्ट किया गया जवाब आज़माएं। –

उत्तर

7

मानक छवि आपको पूरी छवि को पहले स्मृति में पढ़ने के बिना (बड़ी) छवियों के क्षेत्रों को पढ़ने की अनुमति देता है।

Rectangle sourceRegion = new Rectangle(x, y, w, h); // The region you want to extract 

ImageInputStream stream = ImageIO.createImageInputStream(input); // File or input stream 
Iterator<ImageReader> readers = ImageIO.getImageReaders(stream); 

if (readers.hasNext()) { 
    ImageReader reader = readers.next(); 
    reader.setInput(stream); 

    ImageReadParam param = reader.getDefaultReadParam(); 
    param.setSourceRegion(sourceRegion); // Set region 

    BufferedImage image = reader.read(0, param); // Will read only the region specified 
} 
+0

यह अच्छी तरह से काम करता प्रतीत होता है। धन्यवाद। – f3lix

+0

हाय! उस बहुत अच्छे कोड के लिए धन्यवाद snipped। क्या वास्तव में पूरी छवि को पढ़ने के बिना किसी छवि को एक क्षेत्र लिखना संभव है? मेरा क्षेत्र वर्ग में केवल 100 पीएक्स है और मैं इसे एक विशाल जेपीईजी में एक निश्चित स्थान पर स्टोर करना चाहता हूं। – Durin

+0

@ डुरिन हां, यह कुछ फ़ाइल प्रारूपों में संभव हो सकता है। ImageIO एपीआई इसका समर्थन करता है। लेकिन कृपया एक नया सवाल पूछें! :-) – haraldK

0

आप उदाहरण के लिए, का उपयोग कर सकते, RandomAccessFile फ़ाइल के मध्य से पढ़ने के लिए: लेकिन मुद्दा यह है कि पूरे jpeg छवि डीसीटी परिमाणीकरण (http://www.fileformat.info/mirror/egff/ch09_06.htm) के बाद संकुचित है है, इसलिए मुझे नहीं लगता कि यह संभव है कि है स्मृति में पूरी फ़ाइल पढ़ने के बिना एक टुकड़ा पढ़ें।

+1

मेरे पास जेपीईजी और डीसीटी क्वांटिअलाइजेशन का केवल सतही ज्ञान है, लेकिन मेरा मानना ​​है कि डीसीटी 8x8 पिक्सेल ब्लॉक पर लागू होता है और क्षेत्र प्राप्त करने के लिए सभी ब्लॉक को डीकोड करना संभव होना चाहिए। बेशक छवि के अन्य हिस्सों से कुछ गुणांक/जानकारी प्राप्त करना आवश्यक है, लेकिन इसका मतलब यह नहीं है कि मुझे स्मृति में सभी डेटा पढ़ना है ... लेकिन मैं गलत हो सकता था। – f3lix

0

आप जो भी चाहते हैं उसे करने के लिए आप BufferedImage का उपयोग कर सकते हैं।

// Set these variables according to your requirements 
int regionX, regionY, regionWidth, regionHeight;  

BufferedImage image = ImageIO.read(new File("/path/to/image.jpg")); 
BufferedImage region = image.getSubimage(regionX, regionY, regionWidth, regionHeight); 

और फिर आप क्षेत्र उपनिवेश को संसाधित कर सकते हैं, हालांकि आप चाहते हैं।

+0

... लेकिन वह पूरी चीज को स्मृति 1 में पढ़ेगा? – radai

+1

@ रमन: आप मानक दृष्टिकोण का वर्णन करते हैं जो मामूली आकार की छवियों के साथ अच्छी तरह से काम करता है। आप * पूरे * छवि को BufferedImage में पढ़ते हैं और फिर क्षेत्र को निकालते हैं। मेरी समस्या यह है कि इसमें बहुत बड़ी छवियों के साथ बहुत मेमोरी की आवश्यकता होती है, क्योंकि सभी पिक्सल को डीकोड किया जाता है और स्मृति में रखा जाता है। 20,000x30,000 आकार की छवि के लिए इसे लगभग 2 जीबी मेमोरी की आवश्यकता होगी; प्लस, डिकोडर डिकोडिंग पिक्सल पर समय बिताता है जिसका उपयोग कभी नहीं किया जाता है ... – f3lix