जावा छवि को बफ़रडैमेज में परिवर्तित कर रहा है


83

StackOverflow पर इस लिंक की तरह पहले से ही प्रश्न है और स्वीकृत उत्तर "कास्टिंग" है:

Image image = ImageIO.read(new File(file));
BufferedImage buffered = (BufferedImage) image;

अपने कार्यक्रम में मैं कोशिश करता हूं:

final float FACTOR  = 4f;
BufferedImage img = ImageIO.read(new File("graphic.png"));
int scaleX = (int) (img.getWidth() * FACTOR);
int scaleY = (int) (img.getHeight() * FACTOR);
Image image = img.getScaledInstance(scaleX, scaleY, Image.SCALE_SMOOTH);
BufferedImage buffered = (BufferedImage) image;

Unfortunatelly मुझे रन टाइम एरर मिलता है:

sun.awt.image.ToolkitImage को java.awt.image.BufferedImage में नहीं डाला जा सकता है

जाहिर है कि कास्टिंग काम नहीं करती।
प्रश्न है: छवि को बफ़रडैमेज में बदलने का उचित तरीका क्या है (या वहां है)?


यदि आप बफ़र्ड छवि को स्केल करना चाहते हैं, तो यह आज़माएँ [इस stackoverflow.com/questions/4216123/… [1]: stackoverflow.com/questions/4216123/…
user902383

7
रिकॉर्ड के लिए, यह संकलक नहीं है जो कह रहा है कि। आप वास्तव में रनटाइम त्रुटि देख रहे हैं ... संकलन त्रुटि नहीं।
स्टीफन सी

1
तुम सही हो। इस पर ध्यान दिलाने के लिए धन्यवाद। मैं तदनुसार प्रश्न संपादित करूंगा।
आर्य विल्क

@ user902383 भले ही वे सीधे मेरे सवाल का जवाब नहीं दे रहे हैं - वे महान समाधान भी हैं।
विल्क विल

ओपी के लिए छोटी बात: विधि इसके हस्ताक्षर द्वारा ImageIO.read(File)वापस आती है BufferedImage। ( संदर्भ ) पहले एक Imageचर को असाइन करने की आवश्यकता नहीं है फिर टाइप करने के लिए डाली जाती है BufferedImage। यह आपके कोड को पढ़ने वाले लोगों को भ्रमित कर सकता है।
केविनपेयर

जवाबों:


124

से एक जावा गेम इंजन :

/**
 * Converts a given Image into a BufferedImage
 *
 * @param img The Image to be converted
 * @return The converted BufferedImage
 */
public static BufferedImage toBufferedImage(Image img)
{
    if (img instanceof BufferedImage)
    {
        return (BufferedImage) img;
    }

    // Create a buffered image with transparency
    BufferedImage bimage = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);

    // Draw the image on to the buffered image
    Graphics2D bGr = bimage.createGraphics();
    bGr.drawImage(img, 0, 0, null);
    bGr.dispose();

    // Return the buffered image
    return bimage;
}

7
@SriHarshaChilakapati You shouldn't be worrying about the memory when using Java.जावा अनुप्रयोगों द्वारा औसत मेमोरी की खपत को देखते हुए, अन्य डेवलपर्स निश्चित रूप से स्मृति के बारे में थोड़ी चिंता नहीं करते हैं।
टॉम ज़ातो - मोनिका

1
@ TomášZato मुझे लगता है कि आप सी ++ दुनिया से थे, छवि डेटा के पिक्सल की स्मृति का पुन: उपयोग करने के लिए सोच रहे थे। मुझे अपनी पिछली टिप्पणी से मतलब है कि इस मामले में मेमोरी के बारे में चिंता करने की कोई जरूरत नहीं है, क्योंकि जीसी जावा में इसका ध्यान रखेगा।
श्री हर्ष चिलकपति

2
@ श्रीहरिश्चलाकापति तो कचरा बीनने वाले किसी भी संसाधन का उपभोग नहीं करते हैं? जीसी केवल आपको कोड आसपास के मेमोरी से बचाता है । यह एक हार्डवेयर सीमा नहीं मिटाता है।
एंड्रयू सैनियर 3

5
यह काम नहीं किया जाएगा अगर Imageअभी तक लोड नहीं किया गया है, के बाद से getWidth(null)या मामले में getHeight(null)वापस आ जाएगी-1
Dims

1
मुझे BufferedImage.TYPE_INT_RGBअपने थंबनेल का रंग सही पाने के लिए ARGB के बजाय उपयोग करना पड़ा
Stephanie

20

इसे संभालने का एक तरीका एक नया बफ़रमैडम बनाना है, और यह बताना है कि नए बफ़रडैमेज में अपनी स्केल की गई छवि को खींचने के लिए ग्राफिक्स ऑब्जेक्ट:

final float FACTOR  = 4f;
BufferedImage img = ImageIO.read(new File("graphic.png"));
int scaleX = (int) (img.getWidth() * FACTOR);
int scaleY = (int) (img.getHeight() * FACTOR);
Image image = img.getScaledInstance(scaleX, scaleY, Image.SCALE_SMOOTH);
BufferedImage buffered = new BufferedImage(scaleX, scaleY, TYPE);
buffered.getGraphics().drawImage(image, 0, 0 , null);

कि बिना कास्टिंग के चाल चलनी चाहिए।


2
निर्मित ग्राफिक्स उदाहरणों को निपटाना कभी न भूलें
श्री हर्ष चिलकापति

"निर्मित ग्राफिक्स इंटरफेस को कैसे डिस्पोज़ करें"?
भैंस

क्या BufferedImage कंस्ट्रक्टर का प्रकार getScaledInstance में एक से मेल खाना चाहिए?
द्राज़न बेज़ेलोवुक

नहीं, TYPE ARGB या RGBA की तरह कुछ है, जिस तरह से छवि डेटा को आंतरिक रूप से संग्रहीत किया जाता है - वह चुनें जो आपके अनुप्रयोग के लिए सबसे स्वाभाविक रूप से महसूस करता है; बस जब BufferedImage टाइपिंग अपने स्वत: पूर्ण में देखो [स्वत: पूर्ण] सभी विकल्पों को देखने के लिए।
salbeira

3

यदि आप वापस आ रहे हैं sun.awt.image.ToolkitImage, तो आप उस छवि को कास्ट कर सकते हैं, और फिर पाने के लिए getBufferedImage () का उपयोग करें BufferedImage

इसलिए कोड की अपनी अंतिम पंक्ति के बजाय, जहां आप कास्टिंग कर रहे हैं, बस आप ऐसा करेंगे:

BufferedImage buffered = ((ToolkitImage) image).getBufferedImage();

7
1) यह sunपैकेज से कक्षाओं का उपयोग करने के लिए पर आधारित है । वे गैर-ओरेकल JDK में उपलब्ध होने की गारंटी नहीं हैं। 2) विधि getBufferedImage()केवल तभी काम करती है जब बफर इमेज आंतरिक रूप से उत्पन्न हुई हो TookitImage। ज्यादातर (99%) यह नहीं है, इसलिए रिटर्न वैल्यू है nullस्रोत संदर्भ
केविनरपे १ar

3

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

fun Image.toBufferedImage(): BufferedImage {
    if (this is BufferedImage) {
        return this
    }
    val bufferedImage = BufferedImage(this.getWidth(null), this.getHeight(null), BufferedImage.TYPE_INT_ARGB)

    val graphics2D = bufferedImage.createGraphics()
    graphics2D.drawImage(this, 0, 0, null)
    graphics2D.dispose()

    return bufferedImage
}

और इसे इस तरह से उपयोग करें:

myImage.toBufferedImage()
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.