2012-12-19 34 views
14

के लिए आवश्यक बफर आकार की गणना करना मैं WriteableBitmap.WritePixels विधि के लिए आवश्यक बफर आकार की गणना कैसे करूं?WriteableBitmap.WritePixels विधि

मैं अधिभार का उपयोग चार पैरामीटर ले रहा हूं, पहला इंट 32Rect है, अगला एक बाइट सरणी है जिसमें रंग के लिए आरजीबीए संख्याएं हैं, तीसरा है (जो मेरे लिखने योग्य बिटमैप की चौड़ाई है बिट्स प्रति पिक्सेल 8 से विभाजित), और आखिरी बफर (जिसे इंटेलिसेंस में ऑफ़सेट कहा जाता है) है।

मैं बफर आकार नहीं है नीचे दिए गए कोड में पर्याप्त रनटाइम त्रुटि हो रही है:

byte[] colourData = { 0, 0, 0, 0 }; 

var xCoordinate = 1; 
var yCoordinate = 1; 

var width = 2; 
var height = 2; 

var rect = new Int32Rect(xCoordinate, yCoordinate, width, height); 

var writeableBitmap = new WriteableBitmap(MyImage.Source as BitmapSource); 

var stride = width*writeableBitmap.Format.BitsPerPixel/8; 

writeableBitmap.WritePixels(rect, colourData, stride,0); 

क्या है सूत्र मैं ऊपर कोड में आवश्यक बफर मूल्य की गणना करने के लिए उपयोग करने की आवश्यकता है?

+0

जब आप RGBA कहते हैं, आप निश्चित रूप से प्रति पिक्सल 32 बिट है। यह प्रति पिक्सेल 4 बाइट बनाता है। 2x2 रेक्ट में कुल 16 बाइट्स (4 पिक्सल * 4 बाइट्स/प्रति पिक्सेल) है। आपका 'coulorData' स्पष्ट रूप से बहुत छोटा है। – Clemens

+0

@ क्लेमेंस क्या आपका मतलब है कि मेरा स्ट्राइड बहुत छोटा है? यदि आप नहीं समझा सकते हैं कि रंगीन डेटा कितना छोटा है, जैसा कि मुझे समझ में नहीं आता है। धन्यवाद – JMK

+0

स्ट्राइड बस बफर में प्रति पंक्ति बाइट्स की संख्या है। आपके पास 4 बाइट प्रति पिक्सल प्रति पंक्ति 2 पिक्सेल (यानी लिखने आयत की चौड़ाई) है, जिसके परिणामस्वरूप 8. – Clemens

उत्तर

11

कदम मूल्य लिखने आयत में प्रति "पिक्सेल लाइन" बाइट की संख्या के रूप में की जाती है:

var stride = (rect.Width * bitmap.Format.BitsPerPixel + 7)/8; 

आवश्यक बफर आकार लाइनों की संख्या से गुणा प्रति पंक्ति बाइट की संख्या है:

var bufferSize = rect.Height * stride; 

बशर्ते कि आपके पास 2x2 लिखें आयताकार और 32-बिट्स-प्रति-पिक्सेल प्रारूप है, उदाहरण के लिए PixelFormats.Pbgra32, आप प्राप्त stride के रूप में 8 और bufferSize के रूप में 16.

+0

हम्म का एक भाग होता है, अब मुझे एरे त्रुटि के बाहर इंडेक्स मिल रहा है, क्या आपको कोई अंतर्दृष्टि होगी? – JMK

+0

"अब" का अर्थ है कि आपका बफर वास्तव में 16 बाइट लंबा है? – Clemens

+0

यह सही है हाँ – JMK

0

मुझे यकीन है कि नहीं कर रहा हूँ, लेकिन यह 24 बिट rgb

{ 
    //your code 
     var stride = width * 3; 
     WriteableBitmap bmp = new WriteableBitmap(width, height, 96, 96, PixelFormats.Bgr24, null); 
     bmp.WritePixels(new System.Windows.Int32Rect(0, 0, width , height),byte[],stride,0)); 

    } 
+1

के लिए धन्यवाद प्रश्न यह है कि बफर आकार की गणना कैसे करें। – Clemens

+0

और वह कोड संकलित नहीं होगा क्योंकि आप 'पिक्सेल' पैरामीटर के लिए 'बाइट [] 'लिखते हैं। – Clemens

3

लिए काम करता है कदम बस अपने इनपुट बफर के बाइट्स में चौड़ाई है की कोशिश करो। इसे घुमाया जाता है, क्योंकि कभी-कभी छवि की प्रत्येक पंक्ति के पीछे अतिरिक्त स्मृति होती है, जिससे छवि की प्रत्येक पंक्ति को पढ़ने के लिए छवि की चौड़ाई का उपयोग करना असंभव हो जाता है।

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

हालांकि, जैसा कि दूसरे उत्तर में बताया गया है, यदि आपका बिटमैप 2x2 भी है तो आपका उदाहरण काम नहीं करेगा। फिर शुरुआती समन्वय 0,0 होगा।

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

जब मैं अपने उदाहरण में करीब देखो, मैं गलती से देखते हैं। आप कहते हैं कि colourData इनपुट रंग है। लेकिन यह इनपुट प्रति पिक्सेल है। ,

byte[] colourData = { 0, 0, 0, 0, 0, 0, 0, 0, 
         0, 0, 0, 0, 0, 0, 0, 0 }; 

और फिर पिक्सेल प्रति बाइट्स बिटमैप के बराबर है, ताकि 4, बार प्रत्येक लाइन की चौड़ाई (: तो आप 2x2 के एक रेक्ट को बदलना चाहते हैं, तो आपको निम्न inputdata की जरूरत 2), कुल 8.

+0

"तो आपके उदाहरण में, यह 2 है" गलत है। चौराहे 2 (पिक्सल) * 4 (बाइट प्रति पिक्सेल) == 8 (बाइट्स) इसके बजाए है। – Clemens

+0

"आपको बिटमैप के बिट्स प्रति बिट्स के साथ कुछ भी गणना करने की आवश्यकता नहीं है" भी गलत है। लिखने के आयत की चौड़ाई से आगे की गणना करने के लिए, आपको प्रति पिक्सेल बाइट्स की संख्या की आवश्यकता है। – Clemens

+0

उनके उदाहरण में मैं स्पष्ट रूप से देखता हूं कि उसके इनपुट डेटा में 4 बाइट हैं, इसलिए 1 बाइट प्रति पिक्सेल। यह बिटमैप के बाइट्स प्रति पिक्सल के बारे में नहीं है, लेकिन इनपुट डेटा के बाइट्स प्रति पिक्सल के बारे में नहीं है। – Geerten

1

मैं इसके साथ काम कर रहा हूं। 60z FS

this.playerOpacityMaskImage.WritePixels(
       new Int32Rect(0, 0, this.depthWidth, this.depthHeight), 
       this.greenScreenPixelData, 
       this.depthWidth * ((this.playerOpacityMaskImage.Format.BitsPerPixel + 7)/8), 
       0); 
3

यहाँ माइक्रोसॉफ्ट के कोड है कि भीतर CopyPixels

 int num = ((sourceRect.Width * this.Format.BitsPerPixel) + 7)/8; 
     if (stride < num) 
     { 
      throw new ArgumentOutOfRangeException("stride", MS.Internal.PresentationCore.SR.Get("ParameterCannotBeLessThan", new object[] { num })); 
     } 
     int num2 = (stride * (sourceRect.Height - 1)) + num; 
     if (bufferSize < num2) 
     { 
      throw new ArgumentOutOfRangeException("buffer", MS.Internal.PresentationCore.SR.Get("ParameterCannotBeLessThan", new object[] { num2 })); 
     } 
1

हालांकि उपयोगकर्ता क्लेमेंस बफर आकार के विषय में सवाल का जवाब की जांच करता है परिलक्षित है, प्रश्नकर्ता कि वह बफर आकार पहले से ही गणना की जानकारी नहीं थी सही और समस्या कहीं और थी।

जबकि टिप्पणियों में विवरण दिए गए हैं और चर्चा की गई है, वहां एक व्यापक स्निपेट (और .WitePixels (बिना .CopyPixels के) के पूर्ण उपयोग उदाहरण की कमी है। यहाँ यह (मैं इसी तरह के सवाल स्कैन किया है, लेकिन इस सबसे अच्छी जगह किया गया है) है:

var dpiX = 96; 

var writeableBitmap = new WriteableBitmap(width, height, dpiX, dpiX, PixelFormats.Bgra32, null); // Pixelformat of Bgra32 results always in 4 bytes per pixel 
int bytesPerPixel = (writeableBitmap.Format.BitsPerPixel + 7)/8; // general formula 
int stride = bytesPerPixel * width; // general formula valid for all PixelFormats 

byte[] pixelByteArrayOfColors = new byte[stride * height]; // General calculation of buffer size 

// The numbers in the array are indices to the used BitmapPalette, 
//  since we initialized it with null in the writeableBitmap init, they refer directly to RGBA, but only in this case. 
// Choose a light green color for whole bitmap (for not easy to find commented MSDN example with random colors, see https://msdn.microsoft.com/en-us/library/system.windows.media.imaging.writeablebitmap(VS.85).aspx 
for (int pixel = 0; pixel < pixelByteArrayOfColors.Length; pixel += bytesPerPixel) 
{ 
    pixelByteArrayOfColors[pixel] = 0;  // blue (depends normally on BitmapPalette) 
    pixelByteArrayOfColors[pixel + 1] = 255; // green (depends normally on BitmapPalette) 
    pixelByteArrayOfColors[pixel + 2] = 0; // red (depends normally on BitmapPalette) 
    pixelByteArrayOfColors[pixel + 3] = 50; // alpha (depends normally on BitmapPalette) 
} 

writeableBitmap.WritePixels(new Int32Rect(0, 0, width, height), pixelByteArrayOfColors, stride, 0);