2012-03-24 7 views
5

मुझे क्लाइंट विंडो (एक ही आकार) में 1027 * 768 बिटमैप प्रस्तुत करने की आवश्यकता है और मेरे पास इस कार्य को पूरा करने के लिए 10-15 ms से अधिक नहीं है। मैं bufferedGraphics का उपयोग कर रहा हूं bufferedGraphicsContect ऑब्जेक्ट से आवंटित और अभी भी बड़े प्रदर्शन समस्याओं को नोटिस कर रहा हूं।सूचक मैन्युलेशन के माध्यम से ग्राफिक्स सतह को बफर करने के लिए लिखें

मैं असुरक्षित कोड का उपयोग कर रहा मेरी कॉपी ऑपरेशन और अविश्वसनीय परिणाम पाया करने के लिए। मुझे पता है कि ग्राफिक्स/बुफर्डग्राफिक्स ऑब्जेक्ट्स में मेमोरी मेमोरी में ड्राइंग सतह का कुछ प्रकार होना चाहिए। मैं सोच रहा था कि कोई मुझे मार्शल या कुछ अन्य असुरक्षित निम्न स्तर की विधि का उपयोग करके इस सतह पर लिखने के तरीके पर सही दिशा में इंगित कर सकता है।

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

यही वह है जो मैंने अभी तक किया है ... कोई अंतर्दृष्टि जो अब तक बहुत अधिक है।

byte[] _argbs = null; 
static readonly Bitmap _bmUnderlay = Properties.Resources.bg; 
static Bitmap _bmpRender = new Bitmap(1024, 768, System.Drawing.Imaging.PixelFormat.Format24bppRgb); 
int bmpHeight = Properties.Resources.bg.Height; 
int bmpWidth = Properties.Resources.bg.Width; 
static BufferedGraphicsContext _bgc = new BufferedGraphicsContext(); 

internal unsafe void FillBackBuffer(Point cameraPos) 
{ 
     // lock up the parts of the original image to read (parts of it) 
     System.Drawing.Imaging.BitmapData bmd = _bmUnderlay.LockBits(
      new Rectangle(cameraPos.X, cameraPos.Y, 1024, 768), 
      System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb); 
     // get the address of the first line. 
     IntPtr ptr = bmd.Scan0; 

     //if (_argbs == null || _argbs.Length != bmd.Stride * bmd.Height) 
     // _argbs = new byte[bmd.Stride * bmd.Height]; 
     if (_argbs == null || _argbs.Length != 1024 * 3 * 768) 
      _argbs = new byte[1024 * 3 * 768]; 

     // copy data out to a buffer 
     Marshal.Copy(ptr, _argbs, 0, 1024 * 3 * 768); 

     _bmUnderlay.UnlockBits(bmd); 

     // lock the new image to write to (all of it) 
     System.Drawing.Imaging.BitmapData bmdNew = _bmpRender.LockBits(
      new Rectangle(0, 0, 1024, 768), 
      System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format24bppRgb); 
     // copy data to new bitmap 
     Marshal.Copy(_argbs, 0, bmdNew.Scan0, 1024 * 3 * 768); 
     _bmpRender.UnlockBits(bmdNew); 
} 

private unsafe void _btnGo_Click(object sender, EventArgs e) 
{ 
    // less than 2 ms to complete!!!!!!!! 
    FillBackBuffer(new Point()); 

    using (BufferedGraphics bg = _bgc.Allocate(CreateGraphics(), ClientRectangle)) 
    { 
     System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); 
     sw.Start(); 
     ///// 
     /// 
     // This method takes over 17 ms to complete 
     bg.Graphics.DrawImageUnscaled(_bmpRender, new Point()); 
     // 
     /// 
     ///// 
     sw.Start(); 
     this.Text = sw.Elapsed.TotalMilliseconds.ToString(); 

     bg.Render(); 
    } 
} 

संपादित करें:

मैं, Graphics.DrawImage() करने के लिए एक निम्न स्तर विकल्प की तलाश में हूँ अधिमानतः ग्राफिक्स सतह स्मृति के लिए लिख, संकेत का उपयोग कर का उल्लेख भूल गए हैं? धन्यवाद फिर से

+0

मैंने कोड इंडेंटेशन संपादित किया और ऐसा लगता है कि अंत में एक खतरनाक घुंघराले ब्रेस है। अगर यह मेरे अंत में एक समस्या थी, तो कृपया मेरी संपादन – puk

+0

मदद के लिए धन्यवाद, मुझे लगता है कि ब्रेस मेरे स्क्रू का हिस्सा भी है, क्षमा करें :) – OverMars

उत्तर

3

बिटमैप के पिक्सेल प्रारूप पर ध्यान दें। मानक 32 बीपीपी वीडियो हार्डवेयर पर, Format32bppPArgb किसी अन्य की तुलना में दस गुना तेजी से प्रस्तुत करता है। क्योंकि पिक्सेल को किसी भी अनुवाद की आवश्यकता नहीं है। अब आपके द्वारा उपयोग किए जाने वाले 24 बीपीपी प्रारूप को 32 बीपीपी तक बढ़ाया जाना चाहिए और यह मुफ्त में नहीं आता है। पीआरजीबी के पी को न छोड़ें और अल्फा मान को अपने कोड में 255 पर सेट करना न भूलें।

बुफर्डग्राफिक्स का उपयोग करना मछलीपूर्ण बीटीडब्ल्यू है। आपको हमेशा उस व्यक्ति का उपयोग करना चाहिए जिसे आप ऑनपेंट विधि में मुफ्त में प्राप्त करते हैं। और आपको शायद इस की आवश्यकता नहीं है क्योंकि आप इसे तेजी से मार रहे हैं। यह एक स्वचालित 2x गति-अप है।

+0

इससे मुझे उम्मीद से अधिक मदद मिली, धन्यवाद मैं bufferedGraphics का उपयोग करता हूं क्योंकि क्लाइंट विंडो भरने के बाद, मैं बिटमैप्स की कई अन्य परतें जोड़ता हूं! :(सी # इस के लिए इसका मतलब नहीं है ... – OverMars

+0

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

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