2009-08-31 13 views
15

में छवि आकार बदलने की दक्षता मैंने उपयोगकर्ता अपलोड की गई छवियों का आकार बदलने के लिए एक वेब सेवा लिखी है और सभी कार्य एक कार्यात्मक बिंदु से सही ढंग से काम करते हैं, लेकिन यह हर बार CPU उपयोग को स्पाइक करने का कारण बनता है। यह विंडोज सर्वर 2008 64 बिट पर चल रहा है। मैंने 32 और 64 बिट को संकलित करने की कोशिश की है और उसी परिणाम के बारे में जानकारी प्राप्त की है।सी # और .NET 3.5

सेवा के दिल इस समारोह है:

private Image CreateReducedImage(Image imgOrig, Size NewSize) 
{ 
    var newBM = new Bitmap(NewSize.Width, NewSize.Height); 
    using (var newGrapics = Graphics.FromImage(newBM)) 
    { 
     newGrapics.CompositingQuality = CompositingQuality.HighSpeed; 
     newGrapics.SmoothingMode = SmoothingMode.HighSpeed; 
     newGrapics.InterpolationMode = InterpolationMode.HighQualityBicubic; 
     newGrapics.DrawImage(imgOrig, new Rectangle(0, 0, NewSize.Width, NewSize.Height)); 
    } 

    return newBM; 
} 

मैं सेवा पर एक प्रोफाइलर रख दिया और यह इंगित करने के लिए समय के विशाल बहुमत GDI + पुस्तकालय अपने आप में खर्च किया जाता है लग रहा था और वहाँ ज्यादा नहीं है मेरे कोड में प्राप्त किया जाना है।

प्रश्न: क्या मैं यहां अपने कोड में कुछ चमकदार रूप से अक्षम हूं? ऐसा लगता है कि मैंने जो उदाहरण देखा है उसके अनुरूप है।

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

क्या "असुरक्षित कोड" ब्लॉक का उपयोग करके लाभ प्राप्त किया जा सकता है?

अगर मुझे पर्याप्त कोड शामिल नहीं किया गया है तो कृपया मुझे बताएं ... मुझे अनुरोध के रूप में बहुत कुछ करने में खुशी है लेकिन पोस्ट में अप्रिय होना नहीं चाहता।

+0

आप एक तंग पाश में इस चलाते हैं, कितने छवियों/सेकंड तुम क्या इनपुट/आउटपुट छवि आकार में संसाधित कर सकते हैं? –

+0

यदि मैं स्थानीय रूप से कोड के आकार का आकार बदलता हूं तो मैं 45 सेकंड में एक 1000 छवियों का आकार बदल सकता हूं। इनपुट 873x655 और आकार बदल गया और 300x250 तक फसल। –

+0

कुछ निश्चित रूप से गलत है। [एएसपी.नेट के लिए ImageResizer लाइब्रेरी] (http://imageresizing.net) आंतरिक रूप से जीडीआई + का उपयोग करता है और * * * उच्च थ्रूपुट है। मुझे संदेह है कि जिस तरह से I/O को संभाला जाता है - छवि/बिटमैप उदाहरण बनाने से पहले फ़ाइल स्ट्रीम को स्मृति में बफर करना कुछ समरूपता त्रुटियों को समाप्त करता है। –

उत्तर

6

छवि प्रसंस्करण आमतौर पर एक महंगी ऑपरेशन होता है। आपको याद रखना होगा कि आपके ऐप से किसी भी प्रकार की प्रसंस्करण शुरू होने से पहले 32 बिट रंग की छवि को स्मृति में 4 * पिक्सेल चौड़ाई * पिक्सेल ऊंचाई में विस्तारित किया जाता है। एक स्पाइक निश्चित रूप से उम्मीद की जा सकती है खासकर जब किसी भी प्रकार की पिक्सेल प्रोसेसिंग कर रही हो।

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

3

मुझे पता है कि विंडोज 7 के साथ जारी किए गए डायरेक्टएक्स को 2 डी हार्डवेयर त्वरण प्रदान करने के लिए कहा जाता है। चाहे इसका तात्पर्य है कि यह इस प्रकार के ऑपरेशन पर जीडीआई + को हरा देगा, मुझे नहीं पता। एमएस में जीडीआई here का एक सुंदर unflattering विवरण है जिसका तात्पर्य है कि यह अन्य चीजों के अलावा, यह धीमा है।

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

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

2

आप

newGrapics.InterpolationMode = InterpolationMode.Low; 

HighQualityBicubic के रूप में हो जाएगा की कोशिश कर सकते।

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

नीचे की रेखा है, एक छवि का आकार बदलना एक महंगी ऑपरेशन है चाहे आप क्या करें।सबसे आसान समाधान यह है कि आपका मामला बस आपके सर्वर के सीपीयू को एक तेज मॉडल के साथ बदल सकता है।

0

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

2

जब आप लिखना

मैं एक वेब सेवा आकार बदलने के लिए लिखा है प्राप्त करने के लिए उच्च गुणवत्ता Bicubic की आवश्यकता न पड़े हैं उपयोगकर्ता अपलोड की गई छवियां

मुझे लगता है कि उपयोगकर्ता एक (वेब?) सर्वर पर एक छवि अपलोड करता है, और सर्वर स्केलिंग करने के लिए वेब सेवा कहता है?

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

लेकिन मैं बस अनुमान लगा रहा हूं।

पेज। अपने आप में असुरक्षित ब्लॉक कोई लाभ नहीं देते हैं, वे केवल असुरक्षित कोड को संकलित करने की अनुमति देते हैं। तो जब तक कि आप अपना खुद का स्केलिंग रूटिंग नहीं लिखते, एक असुरक्षित ब्लॉक मदद नहीं करेगा।

2

आप ImageMagick को आजमा सकते हैं। यह मुफ़्त है, और एक .NET wrapper भी है: click here। या here। या आप एक डॉस शैल को एक कमांड भेज सकते हैं।

हम बैच प्रोसेसिंग के लिए और कभी कभी एक और अधिक लचीला छवि रूपांतरण के लिए अब और फिर विंडोज सर्वर पर ImageMagick का इस्तेमाल किया है,।

बेशक, वहाँ वाणिज्यिक घटकों के रूप में अच्छी तरह से, Leadtools और Atalasoft द्वारा उन की तरह हैं। हमने कभी कोशिश नहीं की है।