2008-09-24 15 views
24

मैं वर्तमान में निम्नलिखित कोड का उपयोग कर एक छवि वस्तु में पिक्सेल मूल्यों (मूल रूप से एक java.awt.image.PixelGrabber वस्तु के साथ बनाया) की एक सरणी बदल रही है:जावा के इमेजियो के साथ एक छवि ऑब्जेक्ट में पिक्सल की सरणी चालू करें?

public Image getImageFromArray(int[] pixels, int width, int height) { 
    MemoryImageSource mis = new MemoryImageSource(width, height, pixels, 0, width); 
    Toolkit tk = Toolkit.getDefaultToolkit(); 
    return tk.createImage(mis); 
} 

यह संभव प्राप्त करने के लिए एक ही है इमेजियो पैकेज (ओं) से कक्षाओं का उपयोग करके परिणामस्वरूप मुझे एडब्ल्यूटी टूलकिट का उपयोग करने की ज़रूरत नहीं है?

Toolkit.getDefaultToolkit() 100% विश्वसनीय होना प्रतीत नहीं होता है और कभी-कभी एक AWTError फेंक जाएगा, जबकि ImageIO कक्षाओं हमेशा उपलब्ध होना चाहिए, जिसके कारण मैं अपने विधि बदलने में रुचि रखते हूँ।

उत्तर

23

आप ImageIO का उपयोग किये बिना छवि बना सकते हैं। बस पिक्सेल सरणी की सामग्री से मेल खाने वाली छवि प्रकार का उपयोग करके BufferedImage बनाएं।

public static Image getImageFromArray(int[] pixels, int width, int height) { 
      BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); 
      WritableRaster raster = (WritableRaster) image.getData(); 
      raster.setPixels(0,0,width,height,pixels); 
      return image; 
     } 

जब PixelGrabber साथ काम करना, मत भूलना getImageFromArray कॉल करने से पहले पिक्सेल सरणी से RGBA जानकारी निकालने के लिए। PixelGrabber javadoc में handlepixelmethod में इसका एक उदाहरण है। एक बार ऐसा करने के बाद, सुनिश्चित करें कि BufferedImage कन्स्ट्रक्टर में छवि प्रकार BufferedImage.TYPE_INT_ARGB पर सुनिश्चित करें।

+1

धन्यवाद bcash, लेकिन जब मैं उस कोड को आजमाता हूं तो मुझे java.lang.ArrayIndexOutOfBoundsException मिलता है। कोई विचार? –

+0

मुझे लगता है कि यह करीब है, हमें क्रिस से विवरण के साथ अधिक जानकारी की आवश्यकता हो सकती है? ऐसा लगता है कि यह काम करना चाहिए ... आपके इंक क्या हैं? क्या वे आरजीबी हैं? ARGB? कुछ प्रकार के पैक प्रारूप? –

+0

पिक्सेल एक पिक्सेलग्राबर से आ रहे हैं जैसे: int [] पिक्सल = नई int [चौड़ाई * ऊंचाई]; पिक्सेलग्राबर पीजी = नया पिक्सेलग्राबर (आईएमजी, 0, 0, चौड़ाई, ऊंचाई, पिक्सल, 0, चौड़ाई); pg.grabPixels(); –

1

मुझे जावा शॉट (या स्क्रीन का एक सेगमेंट) पकड़ने के लिए java.awt.Robot का उपयोग करके अच्छी सफलता मिली है, लेकिन ImageIO के साथ काम करने के लिए, आपको इसे स्मृति के बजाय BufferedImage में स्टोर करने की आवश्यकता होगी छवि स्रोत। फिर आप ImageIO की एक स्थिर विधि को कॉल कर सकते हैं और फ़ाइल को सहेज सकते हैं। कुछ ऐसा प्रयास करें:

// Capture whole screen 
Rectangle region = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()); 
BufferedImage capturedImage = new Robot().createScreenCapture(region); 

// Save as PNG 
File imageFile = new File("capturedImage.png"); 
ImageIO.write(capturedImage, "png", imageFile); 
7

रास्टर का उपयोग करके मुझे मिला जब भी मैंने TYPE_INT_ARGB के साथ बनाया। हालांकि, setRGB(...)BufferedImage की विधि का उपयोग करने के लिए मेरे लिए काम किया।

+0

मेरे पास एक समान समस्या थी, भले ही इनपुट और आउटपुट का सरणी आकार मिलान हो। मैं भी सेटआरबीबी का उपयोग कर समाप्त हो गया। यह मामूली धीमा हो सकता है लेकिन यह काम करता है। ऐसा नहीं लगता कि अल्फा बनाम गैर-अल्फा को सरणी आकार बदलना चाहिए, हालांकि व्यक्तिगत int पर यह केवल 2 सबसे महत्वपूर्ण बाइट्स है। – bobtheowl2

3

BufferedImage.getData() पर जावाडोक कहता है: "एक रास्टर जो छवि डेटा के कॉपी करता है।"

इस कोड मेरे लिए काम करता है, लेकिन मुझे शक है में यह क्षमता है:

 // Получаем картинку из массива. 
     int[] pixels = new int[width*height]; 
      // Рисуем диагональ. 
      for (int j = 0; j < height; j++) { 
       for (int i = 0; i < width; i++) { 
        if (i == j) { 
         pixels[j*width + i] = Color.RED.getRGB(); 
        } 
        else { 
         pixels[j*width + i] = Color.BLUE.getRGB(); 
         //pixels[j*width + i] = 0x00000000; 
        } 
       } 
      } 

BufferedImage pixelImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);  
    pixelImage.setRGB(0, 0, width, height, pixels, 0, width); 
+1

.. या 'getData()' के बजाय 'getRaster()' का उपयोग करें। – haraldK

0

इस के रूप में, मुझे लगता है कि वहाँ अभी भी एक बेहतर समाधान की गुंजाइश रहती है, भले ही उच्चतम सवाल इतने पर ImageIO के साथ टैग मतदान में से एक है सवाल पुराना है। :-)

गिटहब में मेरे ओपन सोर्स इमेजियो प्रोजेक्ट से BufferedImageFactory.java कक्षा पर एक नज़र डालें।

इसके साथ

, तो आप बस लिख सकते हैं:

BufferedImage image = new BufferedImageFactory(image).getBufferedImage(); 

अन्य अच्छी बात है कि इस दृष्टिकोण, एक सबसे खराब स्थिति के रूप में, एक ही प्रदर्शन (समय) PixelGrabber आधारित उदाहरण के रूप में के बारे में पहले से ही इस में है धागा। अधिकांश सामान्य मामलों (आमतौर पर जेपीईजी) के लिए, यह लगभग दोगुना तेज़ है। किसी भी मामले में, यह कम स्मृति का उपयोग करता है।

एक साइड बोनस के रूप में, मूल छवि के रंगीन मॉडल और पिक्सेल लेआउट को डिफ़ॉल्ट रंग मॉडल के साथ int ARGB में अनुवादित करने के बजाय रखा जाता है। यह अतिरिक्त स्मृति को बचा सकता है।

(पीएस: फैक्ट्री सबस्कलिंग, क्षेत्र-ब्याज और प्रगति श्रोताओं का भी समर्थन करता है यदि कोई दिलचस्पी लेता है।:-)

0

मुझे इस प्रश्न का सही उत्तर लागू करने की कोशिश करने वाले हर किसी की एक ही समस्या थी, मेरे int सरणी को वास्तव में आउटऑफबाउंड अपवाद प्राप्त होता है जहां मैंने इसे एक और अनुक्रमणिका जोड़ना तय किया क्योंकि सरणी की लंबाई विस्तृत होनी चाहिए * ऊंचाई * 3 इस के बाद मैं छवि नहीं मिल सका तो मैं यह छवि

public static Image getImageFromArray(int[] pixels, int width, int height) { 
     BufferedImage image = new BufferedImage(width, height,  BufferedImage.TYPE_INT_ARGB); 
     WritableRaster raster = (WritableRaster) image.getData(); 
     raster.setPixels(0,0,width,height,pixels); 
     image.setData(raster); 
     return image; 
    } 

रेखापुंज स्थापित करने और आप इस

की तरह एक JFrame पर एक लेबल पर छवि देखते हैं, तो यू यह दिखा सकते हैं तय
JFrame frame = new JFrame(); 
    frame.getContentPane().setLayout(new FlowLayout()); 
    frame.getContentPane().add(new JLabel(new ImageIcon(image))); 
    frame.pack(); 
    frame.setVisible(true); 

छवि आइकन() पर छवि सेट करना। अंतिम सलाह आप Bufferedimage.TYPE_INT_ARGB को उस चीज़ से मेल खाने का प्रयास कर सकते हैं जो आपको इस प्रकार से सरणी मिली है, यह बहुत महत्वपूर्ण है कि मेरे पास 0 और -1 की सरणी थी इसलिए मैंने इस प्रकार का उपयोग किया BufferedImage.TYPE_3BYTE_BGR