इस उत्तर को लोड किए गए बड़े बिटमैप से संक्षेप में प्रस्तुत किया गया है
जो कुशलता से बताता है कि डाउन-स्केल किए गए बिटमैप संस्करण को लोड करने के लिए इनसम्प्लीसाइज़ का उपयोग कैसे करें।
विशेष रूप से प्री-स्केलिंग बिटमैप्स विभिन्न विधियों का विवरण बताते हैं, उन्हें कैसे संयोजित करें, और जो सबसे अधिक स्मृति कुशल हैं।
एंड्रॉइड पर बिटमैप को आकार देने के तीन प्रमुख तरीके हैं जिनमें विभिन्न मेमोरी गुण हैं:
createScaledBitmap API
यह एपीआई एक मौजूदा बिटमैप में ले जाएगा, और आपके द्वारा चुने गए सटीक आयामों के साथ एक नया बिटमैप बनाएगा।
प्लस साइड पर, आप वास्तव में उस छवि आकार को प्राप्त कर सकते हैं जिसे आप देख रहे हैं (भले ही यह कैसा दिखता हो)। लेकिन नकारात्मक पक्ष यह है कि इस एपीआई को काम करने के लिए मौजूदा बिटमैप की आवश्यकता होती है । मतलब एक नया, छोटा संस्करण बनाने में सक्षम होने से पहले छवि को लोड करना, डिकोड करना और एक बिटमैप बनाना होगा। यह आपके सटीक आयाम प्राप्त करने के मामले में आदर्श है, लेकिन अतिरिक्त मेमोरी ओवरहेड के मामले में भयानक है। जैसे, यह ज्यादातर ऐप डेवलपर्स के लिए एक सौदा ब्रेकर है जो स्मृति के प्रति सचेत हैं
नमूना चिह्नित करें
BitmapFactory.Options
एक संपत्ति के रूप में उल्लेख किया गया है inSampleSize
कि यह आपकी छवि को आकार देगा, इसे डिकोड करते समय, अस्थायी बिटमैप को डिकोड करने की आवश्यकता से बचने के लिए। यहां उपयोग किया गया यह पूर्णांक मान 1 / x कम आकार पर एक छवि लोड करेगा। उदाहरण के लिए, inSampleSize
2 पर सेट करना एक छवि है जो आधे आकार की है, और इसे 4 पर सेट करने से एक छवि है जो 1 / 4th आकार की है। मूल रूप से छवि आकार हमेशा आपके स्रोत आकार की तुलना में कुछ छोटा-छोटा होगा।
एक मेमोरी के नजरिए से, का उपयोग inSampleSize
करना वास्तव में तेज़ ऑपरेशन है। प्रभावी रूप से, यह आपकी छवि के प्रत्येक Xth पिक्सेल को केवल आपके परिणामी बिटमैप में डिकोड करेगा। inSampleSize
हालांकि इसके साथ दो मुख्य मुद्दे हैं :
यह आपको सटीक संकल्प नहीं देता है । यह केवल 2 की शक्ति से आपके बिटमैप के आकार को घटाता है।
यह सबसे अच्छी गुणवत्ता के आकार का उत्पादन नहीं करता है । अधिकांश आकार बदलने वाले फिल्टर पिक्सेल के ब्लॉक को पढ़कर अच्छी दिखने वाली छवियों का निर्माण करते हैं, और फिर उन्हें आकार देने वाले पिक्सेल का निर्माण प्रश्न में करते हैं। inSampleSize
सिर्फ हर कुछ पिक्सल को पढ़कर यह सब टाल जाता है। परिणाम काफी प्रदर्शन योग्य है, और कम स्मृति है, लेकिन गुणवत्ता ग्रस्त है।
यदि आप केवल अपनी छवि को कुछ pow2 आकार से सिकोड़ने का काम कर रहे हैं, और फ़िल्टर करना कोई समस्या नहीं है, तो आपको अधिक मेमोरी कुशल (या प्रदर्शन कुशल) विधि नहीं मिल सकती है inSampleSize
।
इनकल्ड, इनडेंसिटी, इनरगेट डेंसिटी फ्लैग
यदि आप किसी आयाम है कि दोनों में से एक शक्ति के बराबर नहीं है के लिए एक छवि पैमाने पर करने की जरूरत है, तो आप की आवश्यकता होगी inScaled
, inDensity
और inTargetDensity
के झंडे BitmapOptions
। जब inScaled
झंडा स्थापित किया गया है, प्रणाली स्केलिंग मूल्य व्युत्पन्न जाएगा विभाजित करके अपने बिटमैप को लागू करने के inTargetDensity
द्वारा inDensity
मान।
mBitmapOptions.inScaled = true;
mBitmapOptions.inDensity = srcWidth;
mBitmapOptions.inTargetDensity = dstWidth;
// will load & resize the image to be 1/inSampleSize dimensions
mCurrentBitmap = BitmapFactory.decodeResources(getResources(),
mImageIDs, mBitmapOptions);
इस पद्धति का उपयोग आपकी छवि को फिर से आकार देगा, और इसके लिए एक 'रिसाइज़िंग फ़िल्टर' भी लागू करेगा, अर्थात, अंतिम परिणाम बेहतर दिखेगा, क्योंकि आकार बदलने वाले चरण के दौरान कुछ अतिरिक्त गणित को ध्यान में रखा गया है। लेकिन चेतावनी दी जाए: अतिरिक्त फ़िल्टर चरण, अतिरिक्त प्रसंस्करण समय लेता है , और बड़ी छवियों के लिए जल्दी से जोड़ सकता है, जिसके परिणामस्वरूप धीमी आकार का होता है, और फ़िल्टर के लिए अतिरिक्त मेमोरी आवंटन।
अतिरिक्त फ़िल्टरिंग ओवरहेड के कारण, इस तकनीक को एक ऐसी छवि पर लागू करना एक अच्छा विचार नहीं है जो आपके इच्छित आकार से काफी बड़ा है।
जादू संयोजन
स्मृति और प्रदर्शन के दृष्टिकोण से, आप इन परिणामों को सर्वोत्तम परिणामों के लिए जोड़ सकते हैं। (स्थापित करने inSampleSize
, inScaled
, inDensity
और inTargetDensity
झंडे)
inSampleSize
पहले छवि पर लागू किया जाएगा, इसे अपने लक्ष्य आकार की तुलना में अगले दो LARGER को प्राप्त होगा। फिर, inDensity
& inTargetDensity
का उपयोग सटीक आयामों के परिणाम को स्केल करने के लिए किया जाता है जो आप चाहते हैं, छवि को साफ करने के लिए एक फिल्टर ऑपरेशन को लागू करना।
इन दोनों को मिलाना एक बहुत तेज ऑपरेशन है, क्योंकि इस inSampleSize
कदम से पिक्सल की संख्या कम हो जाएगी, जिसके परिणामस्वरूप घनत्व आधारित कदम के लिए इसे फिल्टर आकार बदलने पर लागू करना होगा।
mBitmapOptions.inScaled = true;
mBitmapOptions.inSampleSize = 4;
mBitmapOptions.inDensity = srcWidth;
mBitmapOptions.inTargetDensity = dstWidth * mBitmapOptions.inSampleSize;
// will load & resize the image to be 1/inSampleSize dimensions
mCurrentBitmap = BitmapFactory.decodeFile(fileName, mBitmapOptions);
यदि आपको विशिष्ट आयामों, और कुछ अच्छे फ़िल्टरिंग के लिए एक छवि को फिट करने की आवश्यकता है , तो यह तकनीक सही आकार प्राप्त करने के लिए सबसे अच्छा पुल है, लेकिन एक तेज, कम-मेमोरी फुटप्रिंट ऑपरेशन में किया जाता है।
छवि आयाम प्राप्त करना
पूरी छवि को डिकोड किए बिना छवि का आकार प्राप्त करना अपने बिटमैप को आकार देने के लिए, आपको आने वाले आयामों को जानना होगा। आप inJustDecodeBounds
छवि के आयाम प्राप्त करने में सहायता के लिए ध्वज का उपयोग कर सकते हैं , वास्तव में पिक्सेल डेटा को डीकोड करने के लिए w / o की आवश्यकता है।
// Decode just the boundaries
mBitmapOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(fileName, mBitmapOptions);
srcWidth = mBitmapOptions.outWidth;
srcHeight = mBitmapOptions.outHeight;
//now go resize the image to the size you want
आप पहले आकार को डीकोड करने के लिए इस ध्वज का उपयोग कर सकते हैं, और फिर अपने लक्ष्य रिज़ॉल्यूशन को स्केल करने के लिए उचित मानों की गणना कर सकते हैं।