दिलचस्प पोस्ट
AJAX, PHP और jQuery का उपयोग कर एकाधिक छवि अपलोड करें पायथन लॉगर को लॉग करने के अलावा सभी संदेशों को stdout में आउटपुट करना जावा विधि से 2 मान वापस कैसे करें? Symfony2 एक डिफ़ॉल्ट विकल्प फ़ील्ड चयन सेट करना संपादन टेक्स्ट के लिए स्वत: सुझाव बंद करें? समतुल्य पंक्तियों का चयन करें क्रोम एक्सटेंशन: सामग्री स्क्रिप्ट में स्थानीय स्टोरेज एक्सेस करना इकाई फ़्रेमवर्क कोड में अनन्य प्रतिबंध प्रथम पायथन में ''> 0 सच क्यों है? "वीएम के आरंभ के दौरान त्रुटि हुई; ऑब्जेक्ट हीप के लिए पर्याप्त स्थान आरक्षित नहीं कर सका "-Xmx3G विजुअल स्टूडियो 2015: इंटेलिसेंस त्रुटियां, लेकिन समाधान संकलन ग्रिडलेआउट फिट आकार स्क्रीन आकार कैसे करें TypeScript निजी सदस्य मैं एक डीजेंगो ऐप के बाहर एक मॉडल को कैसे बदलूं और एक नए में? HTML5 ऑडियो लूपिंग

बिटमैप। क्लोन () और नए बिटमैप (बिटमैप) के बीच क्या अंतर है?

जहाँ तक मैं बता सकता हूं, एक बिटमैप कॉपी करने के दो तरीके हैं।

Bitmap.Clone ()

Bitmap A = new Bitmap("somefile.png"); Bitmap B = (Bitmap)A.Clone(); 

नया बिटमैप ()

 Bitmap A = new Bitmap("somefile.png"); Bitmap B = new Bitmap(A); 

ये दृष्टिकोण अलग कैसे होते हैं? मैं विशेष रूप से स्मृति और सूत्रण के मामले में अंतर में दिलचस्पी रहा हूँ।

वेब के समाधान से एकत्रित समाधान "बिटमैप। क्लोन () और नए बिटमैप (बिटमैप) के बीच क्या अंतर है?"

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

क्लोन () का उपयोग करना बहुत कम उपयोगी है इसके बारे में बहुत से प्रश्न SO में हैं, जहां प्रोग्रामर को उम्मीद है कि क्लोन () बिटमैप के साथ सामान्य समस्या से बचा जाता है, उस फ़ाइल पर लॉक जिस पर वह लोड किया गया था। यह नहीं है केवल उस क्लोन () का उपयोग करें जब आप कोड के संदर्भ पास करते हैं जो बिटमैप को निकालता है और आप ऑब्जेक्ट को नहीं खोना चाहते हैं

पिछली उत्तर पढ़ना, मुझे चिंता है कि पिक्सेल डेटा को बिटमैप के क्लोन किए गए उदाहरणों के बीच साझा किया जाएगा। इसलिए मैंने new Bitmap()Bitmap.Clone() और new Bitmap() बीच अंतर जानने के लिए कुछ परीक्षण किए।

Bitmap.Clone() मूल फ़ाइल लॉक रखता है:

  Bitmap original = new Bitmap("Test.jpg"); Bitmap clone = (Bitmap) original.Clone(); original.Dispose(); File.Delete("Test.jpg"); // Will throw System.IO.IOException 

बजाय new Bitmap(original) का प्रयोग new Bitmap(original) फ़ाइल को original.Dispose() बाद अनलॉक करेगा.निर्देश original.Dispose() , और अपवाद नहीं फेंक दिया जाएगा। क्लोन को संशोधित करने के लिए Graphics क्लास का उपयोग करना ( .Clone() के साथ बनाया गया) मूल को संशोधित नहीं करेगा:

  Bitmap original = new Bitmap("Test.jpg"); Bitmap clone = (Bitmap) original.Clone(); Graphics gfx = Graphics.FromImage(clone); gfx.Clear(Brushes.Magenta); Color c = original.GetPixel(0, 0); // Will not equal Magenta unless present in the original 

इसी तरह, LockBits पद्धति का उपयोग करके मूल और क्लोन के लिए अलग-अलग स्मृति ब्लॉकों की पैदावार होती है:

  Bitmap original = new Bitmap("Test.jpg"); Bitmap clone = (Bitmap) original.Clone(); BitmapData odata = original.LockBits(new Rectangle(0, 0, original.Width, original.Height), ImageLockMode.ReadWrite, original.PixelFormat); BitmapData cdata = clone.LockBits(new Rectangle(0, 0, clone.Width, clone.Height), ImageLockMode.ReadWrite, clone.PixelFormat); Assert.AreNotEqual(odata.Scan0, cdata.Scan0); 

परिणाम object ICloneable.Clone() दोनों के साथ समान हैं Bitmap Bitmap.Clone(Rectangle, PixelFormat) object ICloneable.Clone() और Bitmap Bitmap.Clone(Rectangle, PixelFormat)

इसके बाद, मैंने निम्नलिखित कोड का उपयोग करते हुए कुछ साधारण मानक की कोशिश की।

सूची में 50 प्रतियों को संग्रहित करना 6.2 सेकंडों में ले और 1.7 जीबी मेमोरी उपयोग (मूल छवि 24 बीपीपी और 3456 x 2400 पिक्सल = 25 एमबी) में हुई है:

  Bitmap original = new Bitmap("Test.jpg"); long mem1 = Process.GetCurrentProcess().PrivateMemorySize64; Stopwatch timer = Stopwatch.StartNew(); List<Bitmap> list = new List<Bitmap>(); Random rnd = new Random(); for(int i = 0; i < 50; i++) { list.Add(new Bitmap(original)); } long mem2 = Process.GetCurrentProcess().PrivateMemorySize64; Debug.WriteLine("ElapsedMilliseconds: " + timer.ElapsedMilliseconds); Debug.WriteLine("PrivateMemorySize64: " + (mem2 - mem1)); 

बजाय Clone() का उपयोग करते हुए मैं 0.7 सेकंड के दौरान सूची में 1 000 000 प्रतियां और 0.9 जीबी का उपयोग कर सकता हूं। अपेक्षित होने पर, Clone() new Bitmap() तुलना में बहुत हल्का वजन है:

  for(int i = 0; i < 1000000; i++) { list.Add((Bitmap) original.Clone()); } 

Clone() विधि का इस्तेमाल करने वाले Clone() प्रति-पर-लिखते हैं यहां मैं एक यादृच्छिक पिक्सेल को क्लोन पर यादृच्छिक रंग में बदलता हूं। यह ऑपरेशन मूल से सभी पिक्सेल डेटा की प्रतिलिपि को ट्रिगर करने लगता है, क्योंकि अब हम वापस 7.8 सेकंड और 1.6 जीबी पर हैं:

  Random rnd = new Random(); for(int i = 0; i < 50; i++) { Bitmap clone = (Bitmap) original.Clone(); clone.SetPixel(rnd.Next(clone.Width), rnd.Next(clone.Height), Color.FromArgb(rnd.Next(0x1000000))); list.Add(clone); } 

बस छवि से एक Graphics ऑब्जेक्ट बनाने की प्रतिलिपि ट्रिगर नहीं होगी:

  for(int i = 0; i < 50; i++) { Bitmap clone = (Bitmap) original.Clone(); Graphics.FromImage(clone).Dispose(); list.Add(clone); } 

प्रतिलिपि को ट्रिगर करने के लिए आपको Graphics ऑब्जेक्ट का उपयोग करके कुछ आकर्षित करना होगा अंत में, दूसरी तरफ LockBits का उपयोग करके, डेटा की प्रतिलिपि ImageLockMode.ReadOnly जाएगी, भले ही ImageLockMode.ReadOnly निर्दिष्ट किया गया है:

  for(int i = 0; i < 50; i++) { Bitmap clone = (Bitmap) original.Clone(); BitmapData data = clone.LockBits(new Rectangle(0, 0, clone.Width, clone.Height), ImageLockMode.ReadOnly, clone.PixelFormat); clone.UnlockBits(data); list.Add(clone); }