2009-05-31 19 views
8

मैं एक उचित अनुभवी जावा प्रोग्रामर हूं लेकिन जावा 2 डी के अपेक्षाकृत नया हूं। मैं एक छवि को स्केल करने की कोशिश कर रहा हूं लेकिन मुझे खराब गुणवत्ता के परिणाम मिल रहे हैं। छवि एक पैनल का पूर्वावलोकन है जिसमें टेक्स्ट और टेक्स्टफील्ड जैसी चीज़ें शामिल हैं। मैं हमेशा स्केलिंग करूँगा, कभी नहीं।जावा 2 डी: स्केलिंग मुद्दे

वर्तमान में मैं निम्नलिखित कोड का उपयोग कर रहा: -

g.drawImage(panelImage, 0, 0, scaledWidth, scaledHeight, null); 

कहाँ panelImage पूर्ण आकार पूर्वावलोकन (BufferedImage) और scaledWidth और scaledHeight है संबंधित लक्ष्य आयाम हैं। मुझे टेक्स्टफील्ड इत्यादि जैसी चीजों के टेक्स्ट और किनारों में बहुत अधिक जानकारी मिलती है।

क्या छवि को स्केल करने के लिए मुझे एक बेहतर कॉल का उपयोग करना चाहिए?

धन्यवाद, जॉन

उत्तर

11

एक सुझाव मैं कर सकते हैं पहले एक अलग BufferedImage पर छवि का आकार करने के लिए है। कारण, एक बेहतर गुणवत्ता वाली स्केल छवि बनाने के लिए की Graphics2D ऑब्जेक्ट प्राप्त की जा सकती है।

Graphics2D "प्रतिपादन संकेत" स्वीकार कर सकते हैं जो Graphics2D ऑब्जेक्ट द्वारा छवि प्रसंस्करण के तरीके को निर्देशित करने के निर्देश देते हैं। setRenderingHint विधि उन विधियों में से एक है जिसका उपयोग उन प्रतिपादन संकेतों को सेट करने के लिए किया जा सकता है। RenderingHints कक्षा से प्रतिपादन संकेतों का उपयोग किया जा सकता है।

फिर, Graphics2D ऑब्जेक्ट का उपयोग करके, BufferedImage पर पहले निर्दिष्ट प्रतिपादन संकेतों का उपयोग करके एक छवि खींची जा सकती है।

मोटे (untested) कोड निम्नलिखित के रूप में काम करेगा:

BufferedImage scaledImage = new BufferedImage(
    scaledWidth, 
    scaledHeight, 
    BufferedImage.TYPE_INT_RGB 
); 

Graphics2D g = scaledImage.createGraphics(); 
g.setRenderingHints(
    RenderingHints.Key.KEY_INTERPOLATION, 
    RenderingHints.VALUE_INTERPOLATION_BICUBIC 
); 

g.drawImage(panelImage, 0, 0, scaledWidth, scaledHeight, null); 
g.dispose(); 

अन्य प्रतिपादन ब्याज के संकेत शामिल हो सकते हैं:

Controlling Rendering Quality जावा ट्यूटोरियल के खंड als o Graphics2D ऑब्जेक्ट्स की प्रतिपादन गुणवत्ता को नियंत्रित करने के तरीके के बारे में अधिक जानकारी है।

और सामान्य रूप से ग्राफिकल इंटरफेस से निपटने के बारे में जानकारी के बहुत अच्छे स्रोत के लिए, Filthy Rich Clients चेट हास और रोमेन गाय द्वारा अत्यधिक अनुशंसा की जाती है। पुस्तक का एक वर्ग है जो स्केलिंग छवियों के मुद्दे से संबंधित है, जो काफी प्रासंगिक लगता है।

+0

धन्यवाद, मेरे पास उस पुस्तक की एक प्रति है और मैं अध्याय पढ़ने के लिए इसमें बस गया हूं। पोस्ट करने से पहले वहां देखना चाहिए था। मैं पूरी तरह से स्केलिंग के लिए संकेत प्रस्तुत करने के बारे में भूल गया। धन्यवाद! जॉन – Johnathan

+0

आपका स्वागत है :) पेज 98-113 छवि स्केलिंग से संबंधित है और इसमें कुछ अच्छे उदाहरण भी शामिल हैं। मेरे लिए विशेष रूचि पृष्ठ 104 पर प्रस्तुत प्रगतिशील बिलीनेर स्केलिंग का विचार था। – coobird

+0

हाँ मैंने देखा कि मुझे लगता है कि मेरा एप्लिकेशन वास्तव में इसे वारंट नहीं करता है। BICUBIC या BILINEAR मेरे लिए काफी अच्छे हैं। प्रयोग करने का समय! – Johnathan

2

हो सकता है आप बुलाना चाहिए:

g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); 

और

g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
0

Coobird सही विचार है। मैं RenderingHints.VALUE_INTERPOLATION_BILINEAR इंटरपोलेशन का भी प्रयास करता हूं और देखता हूं कि यह अच्छा दिख रहा है या नहीं। हालांकि, upscaling जब Bicubic बेहतर काम करता है। डाउनस्कलिंग के सर्वोत्तम परिणामों के लिए, कई चरणों में डाउनस्केल होना चाहिए। पहले संकल्प को कम करें, फिर फिर से बंद करें, जब तक कि आप वांछित रिज़ॉल्यूशन के नजदीक न हों (यानी आप आधा नहीं कर सकते हैं या छवि बहुत छोटी हो जाएगी)।अंतिम चरण वांछित संकल्प को स्केल करना है।

उदाहरण के लिए, मान लें कि आपका इनपुट छवि 800x600 है और आप 160x120 को downscale हैं:

  1. downscale 50%। ->400x300
  2. डाउनस्केल 50%। ->200x150
  3. डाउनस्केल 160x120
+0

कई चरणों में डाउनस्कलिंग क्यों लाभान्वित होगी? कृपया विस्तृत करें: डी –

+0

यहां विषय पर कुछ है: http://www.nobel-joergensen.com/roller/java/entry/downscaling_images_in_java इसके अलावा मेरे पास कुछ भी नहीं है, लेकिन मेरे अनुभव में कदमों में कमी एक बेहतर अंत परिणाम प्रदान करता है। कम से कम कोशिश करने के लायक है। :) – MH114

+1

यह "प्रगतिशील बिलीनेर स्केलिंग" के पीछे विचार है - कई चरणों में एक बिलीनेर स्केलिंग करके, प्रत्येक पिक्सेल की जानकारी छवि के एक चरण बिलीनेर rescaling प्रदर्शन से त्यागने के बजाय संरक्षित है। – coobird

1

कोबर्ड सही है कि आपको एक छोटे से पर्याप्त थंबनेल के लिए एक अच्छा दिखने वाला परिणाम प्राप्त करने के लिए वृद्धिशील रूप से डाउन-स्केल (अधिमानतः BICUBIC का उपयोग करना) की आवश्यकता है। Image.getScaledInstance AREA_AVERAGED दृष्टिकोण के साथ ऐसा करने के लिए उपयोग किया जाता है, लेकिन यह क्रिस कैंपबेल द्वारा "छवि के खतरे "getScaledInstance()" आलेख में मूल रूप से प्रस्तावित वृद्धिशील डाउनस्केल की तुलना में बहुत धीमी है।

कृपया यहां स्वयं-प्रचार को क्षमा करें, लेकिन जब imgscalr नामक लाइब्रेरी में चित्र स्केलिंग की बात आती है तो मैंने कुछ "मूल जावा सर्वोत्तम प्रथाओं" को लुभाया।

यह अपाचे 2 लाइसेंस के तहत उपलब्ध है और स्रोत गिटहब पर है; लाइब्रेरी का लक्ष्य देशी जावा मृत-आसान (1 वर्ग, 5 स्थैतिक तरीकों) में छवि-स्केलिंग करना था और सर्वोत्तम दिखने वाला परिणाम सुनिश्चित करना था (जो आप मूल रूप से चाहते थे), सबसे तेज़ परिणाम (बड़ी छवियों के बीच स्केलिंग के दौरान बढ़िया) या दोनों के बीच संतुलन और पुस्तकालय को यह तय करने दें कि किस का उपयोग करना है।

मैं सिर्फ एक lib चाहता था जो "मेरी छवि का आकार बदलें और मेरे रास्ते से बाहर निकल सके" और कुछ दिनों के लिए इन सभी पदों को पढ़ने के बाद मैंने दर्द बिंदु (मेरा स्वयं भी) को संबोधित किया, बस वापस घूम रहा था और साझा कर रहा था किसी और के लिए काम यह मदद कर सकता है।

+0

मूल साइट अभी जवाब नहीं दे रही है, ऐसा लगता है कि lib के लिए आधिकारिक भंडार https://github.com/rkalla/imgscalr –

+0

हां आपको सही रेपो मिला - मैंने सभी पुराने 'द बज़ को बंद कर दिया मीडिया 'सामान (मेरे पास इसे बनाए रखने के लिए लगभग 5 वर्षों का समय नहीं है) और इसे मेरे व्यक्तिगत रेपो स्पेस में ले जाया गया। यह डिफ़ॉल्ट मेवेन रेपो में भी है। –

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