2012-04-18 30 views
9

मुझे वेब वर्कर में सरणी रूप में छवियों को स्केल करने की आवश्यकता है। अगर मैं एक वेब कर्मचारी के बाहर था तो मैं एक छवि के कुछ हिस्सों की प्रतिलिपि बनाने या इसे स्केल करने के लिए कैनवास और ड्रा इमेज का उपयोग कर सकता था।वेब वर्कर और स्केलिंग छवियां

वेब कार्यकर्ता की तरह दिखें मैं कैनवास का उपयोग नहीं कर सकता, तो मैं क्या कर सकता हूं? क्या कोई शुद्ध जावास्क्रिप्ट लाइब्रेरी है जो मेरी मदद कर सकती है?

बहुत पहले से धन्यवाद।

+0

अरे यार मैं आप किसी भी ImageData findf था, ऐसा ही करने की जरूरत है/बाइटएरे आरजीबीए ओवरलैप और पुस्तकालयों या कार्यों को ऊपर/नीचे स्केल करें? – Noitidart

उत्तर

15

स्केलिंग विभिन्न तरीकों से किया जा सकता है, लेकिन वे सभी छवि से पिक्सल को हटाने या बनाने के लिए उबालते हैं। चूंकि छवियां पिक्सेल मानों के अनिवार्य रूप से मैट्रिस (सरणी के रूप में आकार बदलती हैं) हैं, इसलिए आप छवियों को स्केल करने के लिए उस सरणी को विस्तारित करने और रिक्त स्थान भरने और छवियों को स्केल करने के रूप में मूल्यों को छोड़कर सरणी को कम करने के रूप में देख सकते हैं।

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

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

वैसे, अगर आपके पास अपनी छवियों को सरणी के रूप में नहीं है, तो भी आप उसी विधि का उपयोग कर सकते हैं। सबसे पहले कैनवास पर छवि खींचें और फिर Uint8ClampedArray में छवि को पुनर्प्राप्त करने के लिए वर्तमान ImageData ऑब्जेक्ट की डेटा विशेषता का उपयोग करें।

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

दूसरा घटक तब उन रिक्त स्थानों को भरने के लिए है, जो थोड़ा सा सरल हो सकता है। हालांकि, ऐसे कई हैं जो काफी आसान हैं। (दूसरी तरफ, यदि आपके पास कंप्यूटर विजन या इमेज प्रोसेसिंग का कुछ ज्ञान है तो आप कुछ और उन्नत तरीकों को देखना चाहेंगे।) एक आसान और कुछ हद तक स्पष्ट विधि अपने अज्ञात पड़ोसी (यानि निकटतम) का उपयोग करके प्रत्येक अज्ञात पिक्सेल स्थिति को अलग करना है। पिक्सेल मान जिसे जाना जाता है) ज्ञात पिक्सेल के रंग को डुप्लिकेट करके। जब आप छवियों को बहुत अधिक स्केल करते हैं तो यह आम तौर पर बड़े पिक्सल (उसी रंग के बड़े ब्लॉक) के प्रभाव में होता है। निकटतम पिक्सेल के रंग को डुप्लिकेट करने के बजाय, आप आस-पास के कई ज्ञात पिक्सल का औसत भी ले सकते हैं। संभावित रूप से वजन के साथ भी संयुक्त रूप से आप करीब पिक्सल की तुलना में औसत में अधिक पिक्सल गिनती करते हैं जो दूर से दूर होते हैं। अन्य तरीकों में गॉसियन का उपयोग करके छवि को धुंधला करना शामिल है। यदि आप यह जानना चाहते हैं कि आपके आवेदन के लिए कौन सी विधि सबसे अच्छी है, तो छवि इंटरपोलेशन के बारे में कुछ पेज देखें। बेशक, याद रखें कि स्केलिंग का मतलब हमेशा उन सामानों को भरना है जो वास्तव में नहीं हैं। यदि आप इसे बहुत अधिक करते हैं तो हमेशा बुरा लगेगा।

जहां तक ​​स्केलिंग का संबंध है, एक आम तौर पर केवल मौजूदा सरणी से पिक्सेल के चयन को छोटे सरणी में स्थानांतरित करके पिक्सल को हटा देता है।उदाहरण के लिए यदि आप छवि को दो बार छोटे से बनाना चाहते हैं, तो आप मोटे तौर पर 2 के चरणों के साथ वर्तमान सरणी के माध्यम से पुनरावृत्ति करना चाहते हैं (यह छवि के आयामों पर भी थोड़ा सा है, यहां तक ​​कि अजीब है, और यह प्रतिनिधित्व कि आप हैं का उपयोग)। ऐसी विधियां हैं जो उन पिक्सेल को हटाकर इसे और भी बेहतर बनाती हैं जिन्हें सबसे ज्यादा याद किया जा सकता है। लेकिन मैं उनके बारे में पर्याप्त नहीं जानता।

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

इसके अलावा, मुझे यकीन है कि जावास्क्रिप्ट पुस्तकालय हैं जो आपके लिए यह कर सकते हैं और उनके तरीकों के आधार पर आप उन्हें आयात वेब का उपयोग करके अपने वेब वर्कर में भी लोड कर सकते हैं। लेकिन मैं कहूंगा कि इस मामले में यह आसान हो सकता है और इसे स्वयं लिखने की कोशिश करने के लिए बहुत अधिक मजेदार हो सकता है और इसे आपके उद्देश्य के लिए तैयार किया जा सकता है।

और इस पर निर्भर करता है कि आपके प्रोग्रामिंग कौशल कितने उन्नत हैं और जिस गति पर आपको स्केल करने की आवश्यकता है, आप हमेशा WebGL का उपयोग कर CPU पर GPU पर ऐसा करने का प्रयास कर सकते हैं। लेकिन यह इस मामले में थोड़ा सा लगता है। इसके अलावा, आप अपनी छवि को कई टुकड़ों में काटने का प्रयास कर सकते हैं और कई वेब श्रमिकों पर इसे अलग-अलग हिस्सों को स्केल करने का प्रयास कर सकते हैं जो इसे बहु-थ्रेडेड बनाते हैं। हालांकि बाद में भागों को गठबंधन करना निश्चित रूप से तुच्छ नहीं है। शायद बहु-थ्रेडेड अधिक समझ में आता है जब आपके पास बहुत सारी छवियां होती हैं जिन्हें क्लाइंट साइड पर स्केल करने की आवश्यकता होती है।

यह सब वास्तव में आपके आवेदन, छवियों और अपने कौशल और इच्छाओं पर निर्भर करता है।

वैसे भी, मुझे उम्मीद है कि आपके प्रश्न का लगभग जवाब दें।

+0

सभी विवरणों के लिए बहुत बहुत धन्यवाद। और अकेले एक साधारण जावास्क्रिप्ट कार्यान्वयन मेरे मामले में पर्याप्त होगा। –

+1

आदमी ... यह एक जवाब है – Jeremythuff

5

मुझे लगता है कि mslatour के उत्तर पर कुछ विशिष्टताओं की आवश्यकता है, क्योंकि मैंने यह जानने के लिए 6 घंटे बिताए कि कैसे ... ... बस ... अपने स्केल किए गए Uint8ClampedArray ऑब्जेक्ट में अपनी डेटा विशेषता बदलें "। ऐसा करने के लिए:

① वेब-वर्कर से अपनी सरणी वापस भेजें। फार्म का उपयोग करें:

self.postMessage(bufferToReturn, [bufferToReturn]); 

इसकी एक प्रति बनाने के बिना, यदि आप नहीं करना चाहते करने के लिए और वेब कार्यकर्ता से अपने बफर पारित करने के लिए। (यह इस तरह से तेज़ है।) (some MDN documentation, है लेकिन मैं इसे लिंक नहीं कर सकता क्योंकि मैं प्रतिनिधि से बाहर हूं। क्षमा करें।) वैसे भी, आप सूचियों या मानचित्रों के अंदर पहला बफर टॉररेट भी डाल सकते हैं:

self.postMessage({buffer:bufferToReturn, width:500, height:500}, [bufferToReturn]); 

आप एक पोस्ट किए गए संदेश के लिए सुनने के लिए

webWorker.addEventListener('message', function(event) {your code here}) 

की तरह कुछ का उपयोग करें। (इस मामले में, पोस्ट की जाने वाली घटनाएं वेब कार्यकर्ता से होती हैं और सुनवाई करने वाली घटना आपके सामान्य जेएस कोड में होती है। यह वही काम करता है, बस 'स्वयं' और 'वेबवर्कर' चर को चारों ओर स्विच करें।)

② अपने ब्राउज़र-पक्ष जावास्क्रिप्ट (कार्यकर्ता-पक्ष के विपरीत) में, आप imageData .data.set() का उपयोग डेटा विशेषता को "बस" बदलने और इसे कैनवास में वापस रखने के लिए कर सकते हैं।

var imageData = context2d.createImageData(width, height); 
imageData.data.set(new Uint8ClampedArray(bufferToReturn)); 
context2d.putImageData(imageData, x_offset, y_offset); 

मैं मेरे विधि data.set() के अस्तित्व के चेतावनी के लिए hacks.mozilla.org धन्यवाद देना चाहते हैं।

पेज। मैं इसके साथ मदद करने के लिए किसी भी पुस्तकालय के बारे में नहीं जानता ... अभी तक। माफ़ कीजिये।

2

मैं अपने आप को यह परीक्षण करने के लिए अभी तक है, लेकिन एक शुद्ध जे एस पुस्तकालय है कि यहां काम का हो सकता है:

https://github.com/taisel/JS-Image-Resizer

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