2010-12-06 23 views
5

मैं एक छवि के हिस्से को दूसरे छोटे में कॉपी करना चाहता हूं: दूसरे शब्दों में, एक उपखंड को कॉपी करें।मैं एक छवि का हिस्सा दूसरे में कैसे कॉपी करूं?

मैं स्रोत के लिए एक Graphics2D वस्तु है, मैं लक्ष्य के लिए एक कर सकते हैं, और मैं के बारे में targetGraphics2D.drawImage पता (छवि img, ....), लेकिन मुझे लगता है कि कैसे मिलता है imgस्रोत ग्राफिक्स 2 डी से?


उत्तर (aioobe प्रति): स्रोत एक छवि बजाय एक Graphics2D की जरूरत है।

Image.subImage() स्रोत का प्रासंगिक हिस्सा प्राप्त करने का तरीका है।

+2

पता है कि subimage() अंतर्निहित नकल नहीं करती है छवि डेटा, कम से कम BufferedImage के साथ। तो यदि आप subImage() द्वारा प्राप्त छवि पर आकर्षित करते हैं तो आप target.createGraphics() के साथ मूल को भी संशोधित करते हैं। DrawImage (छवि img, ...) वास्तव में आप वास्तव में एक प्रति बनाते हैं। – Trilarion

उत्तर

0

सबसे पहले, कुछ Andreas_D नीचे का जवाब के बारे में नोट्स:

  • उनकी कोड sun.java2d.SunGraphics2D जो एक आंतरिक और गैर-दस्तावेजी OpenJDK वर्ग है पर निर्भर करता है। इसका अर्थ यह है कि, जबकि यह आपके कंप्यूटर पर संकलित और चला सकता है, यह शायद अन्य लोगों को कोड वितरित करने पर शायद टूट जाएगा। विस्तृत चर्चा के लिए, इस बारे में official statement देखें।

  • कोड आंतरिक वर्ग खोलने के प्रतिबिंब पर निर्भर करता है जो स्वयं में एक कोड गंध है।

  • कुल मिलाकर, अपने दृष्टिकोण असाधारण खराब व्यवहार का का एक उदाहरण है (दोनों जब यह प्रोग्रामिंग शैली की बात आती है और जब यह एपीआई सही ढंग से उपयोग करने के लिए साथी प्रोग्रामर की मदद करने के लिए आता है)


मैं sourceGraphics2D से उस img कैसे प्राप्त करूं?

मुझे संदेह है कि आपने Graphics2D कक्षा की ज़िम्मेदारी को गलत समझा।

आप कुछ पर आकर्षित करने के लिए Graphics2D कक्षा का उपयोग करते हैं। यह BufferedImage पर ड्राइंग करने में सक्षम है (यदि आपको एक बफर छवि से ग्राफिक्स ऑब्जेक्ट मिला है), स्क्रीन (यदि आपको इसे paintComponent विधि के लिए तर्क के रूप में मिला है) या यहां तक ​​कि एक प्रिंटर भी है। तो दूसरे शब्दों में, Graphics2D ऑब्जेक्ट्स दिए गए, यहां तक ​​कि एक छवि भी मौजूद नहीं हो सकती है!

तो, जैसा कि आप शायद समझते हैं, Graphics2D एपीआई अंतर्निहित छवि को पकड़ने के तरीकों को प्रदान नहीं करता है। (इस तरह की विधि समझ में नहीं आती है, ग्राफिक्स ऑब्जेक्ट लाइनों और टेक्स्ट को प्रिंटर पर खींचा जा सकता है!)

उपनिवेश प्राप्त करने के लिए आपको अंतर्निहित छवि को पकड़ने की आवश्यकता है जो दिए गए ग्राफिक्स ऑब्जेक्ट पर खिचना।

+0

ठीक है, मैं समझता हूँ। स्रोत को ग्राफिक्स 2 डी की बजाय एक छवि होने की आवश्यकता है। फिर, Image.subImage() क्लिप प्राप्त करने का तरीका है। –

+0

हां। ऐसा कुछ :-) – aioobe

+2

आह चलो, हमेशा एक रास्ता है! (और इस मामले में: "पेंसिल" याद करता है कि उसने क्या खींचा है ;-)) –

3

जैसा कि एओओबे ने कहा था, आपको अकेले ग्राफिक्स 2 डी से छवि नहीं मिल जाएगी।लेकिन अगर आपका स्रोत ग्राफिक्स 2 डी स्विंग घटक से आ रहा है तो आप अपने पेंट विधियों को अपने ग्राफिक्स 2 डी इंस्टेंस के साथ आविष्कार करने का प्रयास कर सकते हैं। वहां से आप दिलचस्प उप-क्षेत्र की प्रतिलिपि बना सकते हैं।

यह एक हैक की तरह है लेकिन यह मानना ​​चाहिए कि आप स्विंग ऑब्जेक्ट्स का उपयोग कर रहे हैं।

class CopySwingPaintingSubRegion extends TheSourceType 
{ 
     private BufferedImage bufImg; 

     public CopySwingPaintingSubRegion() 
     { 
      bufImg = new BufferedImage(...); 

      //Draw the original image into our bufImg for copying 
      super.paintComponent(bufImg.createGraphics()); 
     } 

     public BufferedImage getSubImage(int x, int y, int w, int h) 
     { 
      return bufImg.getSubImage(x,y,w,h); 
     } 
} 
3

लघु जवाब: हां, आप

एक Graphics2D उद्देश्य यह है कि एक बफ़र छवि पर बनाया गया है जानता कर सकते हैं छवि, लेकिन आप के लिए इसे वापस हाथ करने को तैयार नहीं है। यदि आपको प्रतिबिंब का उपयोग करने में कोई फर्क नहीं पड़ता है, तो आप चोरी कर सकते हैं (प्रतिबिंब)। निम्नलिखित कोड को दर्शाता है दृष्टिकोण:

public class Graphics2DReflector { 

    public static void main(String[] args) { 
    // prepare the Graphics2D - note, we don't keep a ref to the image! 
    final Graphics2D g2d = 
      new BufferedImage(100,100,BufferedImage.TYPE_INT_RGB).createGraphics(); 
    g2d.drawString("Reflected", 10, 50); 


    JFrame frame = new JFrame("Reflected Image"); 
    // one Panel to show the image only known by g2d 
    frame.getContentPane().add(new Panel() { 
     @Overwrite 
     public void paint(Graphics g) { 
     try { 
      SurfaceData data = ((SunGraphics2D) g2d).surfaceData; 
      Field bufImg = BufImgSurfaceData.class.getDeclaredField("bufImg"); 
      bufImg.setAccessible(true); 
      BufferedImage image = (BufferedImage) bufImg.get(data); 
      g.drawImage(image,0,0,null); 
     } catch (Exception oops) { 
      oops.printStackTrace(); 
     } 
     } 
    }); 
    frame.setSize(200,200); 
    frame.setVisible(); 
    } 
} 

नोट: इस कुछ सूर्य/Oracle वर्गों पर निर्भर करता है और सभी जावा VMs के साथ काम नहीं कर सकते हैं। कम से कम यह एक दृष्टिकोण दिखाता है और आपको फ़ील्ड प्राप्त करने के लिए वास्तविक कक्षाओं का निरीक्षण करना पड़ सकता है।

+1

'सूर्य' * 'पैकेज और उसी उत्तर में प्रतिबिंब दोनों पर भरोसा करता है .. हेहे;) आपको शायद कम से कम परिस्थितियों को सूचीबद्ध करना चाहिए जो 'Graphics2D' ऑब्जेक्ट वास्तव में * है * एक 'SunGraphics2D' है? पढ़ें [डेवलपर्स को प्रोग्राम क्यों नहीं लिखना चाहिए वह कॉल 'सूर्य' पैकेज] (http://java.sun.com/products/jdk/faq/faq-sun-packages.html)। – aioobe

+1

@aiobe - अरे, यह एक हैक है और मैंने पहले ही उन सीमाओं के लिए एक सामान्य नोट जोड़ा है। आपने कहा कि यह काम नहीं करता है और मैंने अभी जवाब दिया: यह संभव है। बिल्कुल पोर्टेबल नहीं लेकिन असंभव नहीं है। –

1

अगर मैं इसे सही समझता हूं, W3Schools में कैनवास डालने के लिए छवि का हिस्सा पाने के लिए कोड है। यदि आपको इसे किसी अन्य छवि के रूप में चाहिए तो आप इसे उस कैनवास से प्राप्त कर सकते हैं।

मैं एक PNG छवि 20 लंबा 200 विस्तृत द्वारा किया है कि 10 "कोशिकाओं या फ्रेम" है - क्या मैं एनीमेशन के लिए इस्तेमाल करते हैं और नीचे दी गई विधि का उपयोग करें:

context.drawImage(img, sx, sy, swidth, sheight, x, y, width, height); 
संबंधित मुद्दे