2012-12-08 11 views
5

मेरे पास एक सर्वर सॉकेट और सॉकेट सेट अप है, इसलिए ServerSocket ImageIO.write (....) का उपयोग करके छवियों की एक स्ट्रीम भेजता है और सॉकेट उन्हें पढ़ने और उनके साथ जेएफआरएएम अपडेट करने का प्रयास करता है। तो मुझे आश्चर्य हुआ कि क्या छविआई छवि के अंत का पता लगा सकता है। (मुझे जेपीईजी प्रारूप का बिल्कुल कोई ज्ञान नहीं है, इसलिए मैंने इसके बजाय परीक्षण किया)ImageIO का उपयोग कर छवियों की एक धारा भेजें?

जाहिर है, नहीं।

सर्वर की तरफ, मैंने छवियों को लिखने के साथ छवियों को लिखने के साथ लगातार छवियां भेजीं।()) लूप में कुछ नींद के साथ। क्लाइंट साइड पर, इमेजियो ने पहली छवि को कोई समस्या नहीं पढ़ी, लेकिन अगले पर यह शून्य हो गया। यह भ्रामक है। मैं उम्मीद कर रहा था कि यह पहली छवि को पढ़ने पर रोक देगा (क्योंकि ऐसा लगता है कि अगली छवि अभी भी एक ही छवि का हिस्सा है), या उन सभी को पढ़ने में सफल रही है (क्योंकि यह काम करती है)। क्या हो रहा है? ऐसा लगता है कि इमेजियो पहली छवि के अंत का पता लगाता है, लेकिन दूसरा नहीं। (वैसे, छवियां, मोटे तौर पर एक-दूसरे के समान होती हैं) क्या इस तरह की छवियों को स्ट्रीम करने का कोई आसान तरीका है या क्या मुझे अपना स्वयं का तंत्र बनाना है जो बाइट्स को बफर में पढ़ता है जब तक कि यह निर्दिष्ट बाइट या अनुक्रम तक नहीं पहुंच जाता बाइट्स, किस बिंदु पर यह बफर से छवि को पढ़ता है?

यह अपने सर्वर कोड की उपयोगी हिस्सा है:

 while(true){ 
      Socket sock=s.accept(); 
      System.out.println("Connection"); 
      OutputStream out=sock.getOutputStream(); 
      while(!socket.isClosed()){ 
       BufferedImage img=//get image 
       ImageIO.write(img, "jpg", out); 
       Thread.sleep(100); 
      } 
      System.out.println("Closed"); 
     } 

और मेरे मुवक्किल कोड:

 Socket s=new Socket(InetAddress.getByName("localhost"), 1998); 
     InputStream in=s.getInputStream(); 
     while(!s.isClosed()){ 
      BufferedImage img=ImageIO.read(in); 
      if(img==null)//this is what happens on the SECOND image 
      else // do something useful with the image 
     } 
+0

यहां तक ​​कि वीडर: मैंने ImageIO.write के लिए प्रारूप को पीएनजी पर सेट किया है, और यह काम करता है (अच्छी तरह से, कुछ हद तक। प्राप्त छवियों में से आधा शून्य था) – DankMemes

+0

ऐसा लगता है कि मुझे बफरिंग सिस्टम को सभी के बाद लागू करना होगा। :( – DankMemes

+1

* "ImageIO.write (....) का उपयोग कर छवियों की एक धारा और सॉकेट उन्हें पढ़ने और उनके साथ एक जेएफआरएएम अपडेट करने का प्रयास करता है।" * यदि यह वेब चैट या स्क्रीन-शेयरिंग या इसी तरह के नोट के लिए है, तो नोट कि इसमें वीडियो धाराओं या बुद्धिमानी से कम छवियों की आवश्यकता होती है (उदाहरण के लिए स्क्रीन-कास्ट के लिए केवल बदले गए क्षेत्र की फसल)। व्यक्तिगत छवियों को भेजना परिणामस्वरूप वीडियो को ग्लेशियर की तरह स्प्रिंट करना होगा (वैश्विक जलवायु परिवर्तन को अनदेखा करना)। –

उत्तर

4

ImageIO.read(InputStream) एक ImageInputStream बनाता है और आंतरिक रूप से read(ImageInputStream) कहता है। उस बाद की विधि को स्ट्रीम को बंद करने के लिए प्रलेखित किया जाता है जब यह छवि को पढ़ा जाता है।

तो, सिद्धांत रूप में, तुम सिर्फ ImageReader प्राप्त कर सकते हैं, एक ImageInputStream खुद बनाते हैं, और ImageInputStream बार-बार से ImageReader पढ़ा है।

छोड़कर, ऐसा लगता है कि यह एक ImageInputStream एक और एक छवि के साथ काम करने के लिए डिज़ाइन किया गया है (जिसमें एकाधिक फ़्रेम शामिल हो सकते हैं या नहीं)। यदि आप ImageReader.read(0) को एक से अधिक बार कॉल करते हैं, तो यह आपको प्रत्येक बार (कैश किए गए) स्ट्रीम डेटा की शुरुआत के लिए रिवाइंड करेगा, जिससे आपको एक ही छवि मिल जाएगी। ImageReader.read(1) एक बहु-फ्रेम छवि में एक दूसरे फ्रेम की तलाश करेगा, जो निश्चित रूप से एक जेपीईजी के साथ कोई समझ नहीं आता है।

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

आपकी अंतर्निहित धारा की स्थिति के निश्चित होने का एकमात्र तरीका mark और reset के साथ है। चूंकि छवियां बड़ी हो सकती हैं, इसलिए आपको readLimit को अनुमति देने के लिए शायद BufferedInputStream की आवश्यकता होगी।

यह मेरे लिए काम किया:

private static final int MAX_IMAGE_SIZE = 50 * 1024 * 1024; 

static void readImages(InputStream stream) 
throws IOException { 
    stream = new BufferedInputStream(stream); 

    while (true) { 
     stream.mark(MAX_IMAGE_SIZE); 

     ImageInputStream imgStream = 
      ImageIO.createImageInputStream(stream); 

     Iterator<ImageReader> i = 
      ImageIO.getImageReaders(imgStream); 
     if (!i.hasNext()) { 
      logger.log(Level.FINE, "No ImageReaders found, exiting."); 
      break; 
     } 

     ImageReader reader = i.next(); 
     reader.setInput(imgStream); 

     BufferedImage image = reader.read(0); 
     if (image == null) { 
      logger.log(Level.FINE, "No more images to read, exiting."); 
      break; 
     } 

     logger.log(Level.INFO, 
      "Read {0,number}\u00d7{1,number} image", 
      new Object[] { image.getWidth(), image.getHeight() }); 

     long bytesRead = imgStream.getStreamPosition(); 

     stream.reset(); 
     stream.skip(bytesRead); 
    } 
} 
0

शायद नहीं इष्टतम तरीका यह है जबकि निम्न कोड मुद्दा अपने होने अतीत आप मिलेगा। जैसा कि पिछले जवाब में बताया गया है कि इमेजियो छवि के अंत में स्ट्रीम नहीं छोड़ रहा है, यह अगली छवि के लिए रास्ता तय करेगा।

int imageCount = in.read(); 
for (int i = 0; i < imageCount; i ++){ 
    BufferedImage img = ImageIO.read(in); 
    while (img == null){img = ImageIO.read(in);} 
    //Do what ever with img 
} 
0

मैं एक ही समस्या मारा और इस पोस्ट पाया। @ वीजीआर की टिप्पणी ने मुझे समस्या में खोदने के लिए प्रेरित किया, अंततः मुझे एहसास हुआ कि ImageIO एक ही स्ट्रीम में छवियों के एक सेट से निपट नहीं सकता है। इसलिए मैंने समाधान बनाया है (स्कैला में, माफ करना) और ब्लॉग विवरण को कुछ विवरण और आंतरिक के साथ लिखा है।

http://blog.animatron.com/post/80779366767/a-fix-for-imageio-making-animated-gifs-from-streaming

शायद यह रूप में अच्छी तरह किसी को मदद मिलेगी।

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