2010-03-30 15 views
6

के रूप में प्रदर्शित करना मैं एक ऐसा एप्लिकेशन लिख रहा हूं जो इमेज इंकन्स (जेएलएबल के भीतर) के रूप में छवियों को पढ़ता और प्रदर्शित करता है, एप्लिकेशन को जेपीईजी और बिटमैप्स का समर्थन करने में सक्षम होना चाहिए।जावा: छवियों को पढ़ना और छवि आइकन

jpegs के लिए मुझे लगता है कि फ़ाइल आइकन को सीधे इमेज आइकन कन्स्ट्रक्टर पर पास करना ठीक काम करता है (यहां तक ​​कि दो बड़े jpegs प्रदर्शित करने के लिए भी), हालांकि अगर मैं छवि प्राप्त करने के लिए ImageIO.read का उपयोग करता हूं और फिर छवि को छवि आइकन कन्स्ट्रक्टर में पास करता हूं, I दूसरी छवि पढ़ी जाने पर आउटऑफमेमरी एरर (जावा हीप स्पेस) प्राप्त करें (पहले की तरह ही छवियों का उपयोग करें)।

बिटमैप्स के लिए, यदि मैं छवि आइकन पर फ़ाइल नाम पास करके पढ़ने की कोशिश करता हूं, तो छवियों के साथ छवि को पढ़कर और छवि इंक कन्स्ट्रक्टर में इस छवि का उपयोग करके कुछ भी प्रदर्शित नहीं होता है।

मैं अन्य फ़ोरम पोस्ट पढ़ने से समझता हूं कि विभिन्न विधियों के लिए दो विधियां समान कार्य नहीं करती हैं, इसलिए बिटमैप्स के साथ जावा की संगतता समस्याएं नीचे आती हैं, हालांकि मेरी समस्या के आसपास एक तरीका है ताकि मैं उपयोग कर सकूं OutOfMemoryError के बिना बिटमैप्स और jpegs दोनों के लिए एक ही विधि?

(मैं ढेर आकार यदि संभव हो तो बढ़ाने के लिए होने से बचने के लिए करना चाहते हैं!)

OutOfMemoryError इस लाइन से शुरू हो रहा है:

img = getFileContentsAsImage(file); 

और विधि परिभाषा है:

public static BufferedImage getFileContentsAsImage(File file) throws FileNotFoundException { 
    BufferedImage img = null; 
    try { 
    ImageIO.setUseCache(false); 
    img = ImageIO.read(file); 
    img.flush(); 
    } catch (IOException ex) { 
    //log error 
    } 
return img; 
} 

स्टैक ट्रेस है:

Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space 
     at java.awt.image.DataBufferByte.<init>(DataBufferByte.java:58) 
     at java.awt.image.ComponentSampleModel.createDataBuffer(ComponentSampleModel.java:397) 
     at java.awt.image.Raster.createWritableRaster(Raster.java:938) 
     at javax.imageio.ImageTypeSpecifier.createBufferedImage(ImageTypeSpecifier.java:1056) 
     at javax.imageio.ImageReader.getDestination(ImageReader.java:2879) 
     at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(JPEGImageReader.java:925) 
     at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(JPEGImageReader.java:897) 
     at javax.imageio.ImageIO.read(ImageIO.java:1422) 
     at javax.imageio.ImageIO.read(ImageIO.java:1282) 
     at framework.FileUtils.getFileContentsAsImage(FileUtils.java:33) 
+0

कृपया कुछ नमूना कोड पोस्ट करें जो OutOfMemoryError को ट्रिगर करता है। – Thomas

उत्तर

3

आप स्मृति से बाहर हो रहे हैं क्योंकि ImageIO.read() एक असम्पीडित BufferedImage देता है जो बहुत बड़ा है और ढेर में बनाए रखा गया है क्योंकि इसे ImageIcon द्वारा संदर्भित किया गया है। हालांकि, Toolkit.createImage द्वारा लौटाए गए चित्रों को संपीड़ित प्रारूप में रहते हैं (निजी ByteArrayImageSource वर्ग का उपयोग कर।)

आप एक बीएमपी Toolkit.createImage का उपयोग कर नहीं पढ़ सकते हैं (और यहां तक ​​कि यदि आप इसे अभी भी स्मृति में असम्पीडित रहेगा सकता है और आप शायद बाहर चलाने के लिए होगा ढेर अंतरिक्ष फिर से) लेकिन आप क्या कर सकते हैं असम्पीडित छवि को पढ़ा है और इसे संकुचित रूप में बाइट सरणी में सहेजना है, उदाहरण के लिए

public static ImageIcon getPNGIconFromFile(File file) throws IOException { 
    BufferedImage bitmap = ImageIO.read(file); 
    ByteArrayOutputStream bytes = new ByteArrayOutputStream(); 
    ImageIO.write(bitmap, "PNG", bytes); 
    return new ImageIcon(bytes.toByteArray()); 
} 

इस तरह केवल समय असम्पीडित बिटमैप स्मृति में आयोजित किया जाना चाहिए, जब यह भरा हुआ है या गाया जा रहा है।

+0

शानदार! यह पूरी तरह से काम करता है। बस ब्याज से बाहर यह विधि केवल बिटमैप फ़ाइल का उपयोग करते समय प्रारूप नाम के रूप में "पीएनजी" का उपयोग करके क्यों काम करती है? – 11helen

+0

इसे एक प्रारूप होना चाहिए जो टूलकिट द्वारा पठनीय है और इसके लिए एक छविियो प्लगइन होना आवश्यक है। जीआईएफ शायद काम करेगा (लेकिन 8 बीपीपी तक सीमित है इसलिए गुणवत्ता कम हो सकती है।) जेपीईजी भी काम करेगा (लेकिन फोटोग्राफिक छवियों के लिए सबसे अच्छा काम करता है, जो शायद पहले से ही जेपीईजी प्रारूप में थे इसलिए यह अनावश्यक होगा।) – finnw

0

क्या आपने यह कोशिश की है?

ImageIcon im = new ImageIcon(Toolkit.getDefaultToolkit().createImage("filename")); 
+0

यह बिटमैप्स के साथ काम नहीं करता है और 2 बड़े jpegs के साथ भी विफल रहता है: थ्रेड में अपवाद "छवि Fetcher 0" java.lang.OutOfMemoryError: जावा हीप स्पेस java.awt.image.DataBufferInt पर। (DataBufferInt.java:41) java.awt.image.Raster.createPackedRaster (Raster.java:458) पर java.awt.image.DirectColorModel.createCompatibleWritableRaster (DirectColorModel.java:1015) पर sun.awt पर । image.ImageRepresentation।createBufferedImage (ImageRepresentation.java3030) sun.awt.image.ImageRepresentation.setPixels (ImageRepresentation.java:470) ... – 11helen

0

यह नहीं हो सकता कि आप वास्तव में स्मृति से बाहर हो जाएं? मेरा मतलब है, क्या त्रुटि तब भी होती है जब आप जावा को चलाते हैं, कहें, -Xmx1g?

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