2013-02-07 57 views
6

मुझे लगता है कि मुझे सी # में बिटमैप्स की प्रतिलिपि बनाने का एक बहुत तेज़ तरीका मिला है। (यदि यह मान्य है, तो मुझे यकीन है कि मैं पहले नहीं था लेकिन मैंने इसे अभी तक कहीं नहीं देखा है।)क्या यह सुरक्षित है (पन इरादा) इस तरह लॉकबिट का उपयोग करके बिटमैप क्षेत्रों की प्रतिलिपि बनाने के लिए?

यह पूछने का सबसे आसान तरीका यह है कि मैं अपने विचार पर आधारित हूं और यदि कोई भी गोली मारता है उस में छेद, मान विचार आवाज़ है:

void FastCopyRegion(Bitmap CopyMe, ref Bitmap IntoMe, Rectangle CopyArea) 
    { 
     //`IntoMe` need not be declared `ref` but it brings 
     // attention to the fact it will be modified 
     Debug.Assert(CopyMe.PixelFormat == IntoMe.PixelFormat, 
      "PixelFormat mismatch, we could have a problem"); 
     Debug.Assert(CopyMe.Width == IntoMe.Width, //This check does not verify 
      "Stride mismatch, we could have a problem");// sign of `stride` match 
     BitmapData copyData = CopyMe.LockBits(CopyArea, 
      ImageLockMode.ReadWrite, CopyMe.PixelFormat); 
     IntoMe.UnlockBits(copyData); 
    } 

1) LockBits बस तय स्मृति के लिए एक बिटमैप से बाहर पिक्सेल डेटा का एक ब्लॉक प्रतियां संपादित और UnlockBits

का उपयोग करके फिर कॉपी करने के लिए 2) LockBits का उपयोग प्रतिलिपि मेमोरी ब्लॉक को प्रभावित नहीं करता है, इसलिए इसकी प्रतिलिपि बनाई गई छवि पर इसका कोई प्रभाव नहीं होना चाहिए।

3) चूंकि आप कभी भी unsafe कोड दर्ज नहीं करते हैं, इसलिए स्मृति को दूषित करने का कोई जोखिम नहीं होना चाहिए।

संभव छेद मैं देख रहा हूँ:

1) दो बिटमैप्स का PixelFormat रों भिन्न हैं, तो इस विधि हमेशा सही ढंग से नकल नहीं कर सकते। हालांकि, LockBits के बाद से एक पिक्सेलफॉर्म निर्दिष्ट करने की आवश्यकता है, ऐसा लगता है कि यह संभाला जाता है। (यदि हां, तो उस ओवरहेड के लिए हुरेय 99.9% समय हम पिक्सेलफॉर्मेट्स स्विच नहीं कर रहे हैं!/एंडस्कासम)

2) यदि दो बिटमैप्स का सामना नहीं होता है, तो कोई समस्या हो सकती है (क्योंकि stride प्रतिलिपि ऑपरेशन में लूप के incrementor के लिए बाहरी है।) यह समस्या बराबर stride के साथ बिटमैप पर प्रतिलिपि सीमित करेगा।

संपादित करें: मुझे लगता है कि दावा # 2 गलत होना चाहिए ... बाद में मुझे CopyMe के माध्यम से पारित बिटमैप तक पहुंचने का प्रयास करते समय एक त्रुटि मिली। नीचे कामकाज, लेकिन मुझे यकीन नहीं है कि यह निश्चित स्मृति के एक ब्लॉक को चारों ओर झूठ बोलता है। (मेमोरी लीक अलर्ट!)

void FastCopyRegion(Bitmap CopyMe, ref Bitmap IntoMe, Rectangle CopyArea) 
    { 
     //`IntoMe` need not be declared `ref` but it brings attention to the fact it will be modified 
     Debug.Assert(CopyMe.PixelFormat == IntoMe.PixelFormat, "PixelFormat mismatch, we could have a problem"); 
     Debug.Assert(CopyMe.Width == IntoMe.Width, "Width mismatch, we could have a problem"); 
     BitmapData copyD = IntoMe.LockBits(CopyArea, ImageLockMode.ReadWrite, CopyMe.PixelFormat); 
     BitmapData copyData = CopyMe.LockBits(CopyArea, ImageLockMode.ReadWrite, CopyMe.PixelFormat); 
     CopyMe.UnlockBits(copyData); 
     IntoMe.UnlockBits(copyData); 
    } 
+5

प्रश्न भूल गए, मुझे पन समझ में नहीं आया ?! – LukeHennerley

+0

@LukeHennerley आम तौर पर यदि आप 'लॉकबिट्स' का उपयोग करने जा रहे हैं, तो आप सीधे स्मृति तक पहुंचने के लिए 'असुरक्षित' कोड के साथ इसका पालन करेंगे। मैं 'लॉकबिट्स 'का उपयोग कर रहा हूं और' असुरक्षित 'कोड नहीं कर रहा हूं। – AppFzx

+3

यह काफी विशिष्ट है, जीडीआई + में सामान्य रूप से बहुत ही अपमानजनक अपवाद रिपोर्टिंग है और इसके बदला लेने में देरी करने के लिए उपयुक्त है। इसके बजाय Bitmap.Clone() का उपयोग करें। –

उत्तर

3

इसके बजाय Bitmap.Clone() का उपयोग करें। जीडीआई + अपवादों की रिपोर्ट नहीं करता है और परिणामस्वरूप बग ट्रैक करना बहुत कठिन होगा।

एक बहुत तेजी तरह से एक बिटमैप में छवियों को कॉपी करने के लिए जब तक आप पिक्सेल प्रारूप न करने वाली के रूप में या छवि पैमाने Graphics.DrawImage()के साथ है।

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

  • कोई संबंधित समस्या नहीं^_^