2010-09-06 18 views
17

मैं ऑब्जेक्ट का उपयोग करते हुए एक स्रोत Bitmap और अल्फा मास्क Bitmap के साथ एक छवि खींचने की कोशिश कर रहा हूं। फिलहाल मैं लूप एक्स और वाई लूप और GetPixel और SetPixel का उपयोग स्रोत रंग और मास्क अल्फा को तीसरे Bitmap पर लिखने के लिए करता हूं, और उसके बाद इसे प्रस्तुत करता हूं। हालांकि यह बहुत अक्षम है और मैं सोच रहा हूं कि इसे प्राप्त करने का एक तेज तरीका है या नहीं?सी # सिस्टम में अल्फा मास्किंग। ड्रॉइंग?

प्रभाव मैं इस तरह दिखता है के बाद कर रहा हूँ:

Effect I’m after

ग्रिड पैटर्न पारदर्शिता प्रतिनिधित्व करता है; आप शायद यह जानते थे।

+2

चूंकि आप कहते हैं कि आप सिस्टम का उपयोग कर रहे हैं। ड्रॉइंग.ग्राफिक्स, यह शायद ऑफ-विषय है, लेकिन यहां WPF में अस्पष्टता मास्क का एक लिंक है, जो हार्डवेयर त्वरण का लाभ उठाएगा: http://msdn.microsoft.com/ en-us/library/system.windows.media.drawinggroup.opacitymask.aspx – Douglas

+0

ऑफ-विषय, लेकिन फिर भी आकर्षक - धन्यवाद! – Origamiguy

उत्तर

15

हाँ, यह करने के लिए तेजी से रास्ता Bitmap.LockBits का उपयोग करें और सूचक अंकगणित का उपयोग GetPixel और SetPixel के बजाय मूल्यों को पुनः प्राप्त करने के लिए है। निश्चित रूप से नकारात्मक बात यह है कि आपको असुरक्षित कोड का उपयोग करना होगा; यदि आप कोई गलती करते हैं, तो आप अपने कार्यक्रम में कुछ वाकई खराब क्रैश कर सकते हैं। लेकिन अगर आप इसे सरल और आत्मनिर्भर रखते हैं, तो यह ठीक होना चाहिए (हे, अगर मैं कर सकता हूं, तो आप इसे भी कर सकते हैं)।

उदाहरण के लिए, आप (अपने जोखिम पर परीक्षण नहीं किया, उपयोग) कुछ इस तरह कर सकता है:

Bitmap mask = ...; 
Bitmap input = ...; 

Bitmap output = new Bitmap(input.Width, input.Height, PixelFormat.Format32bppArgb); 
var rect = new Rectangle(0, 0, input.Width, input.Height); 
var bitsMask = mask.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); 
var bitsInput = input.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); 
var bitsOutput = output.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); 
unsafe 
{ 
    for (int y = 0; y < input.Height; y++) 
    { 
     byte* ptrMask = (byte*) bitsMask.Scan0 + y * bitsMask.Stride; 
     byte* ptrInput = (byte*) bitsInput.Scan0 + y * bitsInput.Stride; 
     byte* ptrOutput = (byte*) bitsOutput.Scan0 + y * bitsOutput.Stride; 
     for (int x = 0; x < input.Width; x++) 
     { 
      ptrOutput[4 * x] = ptrInput[4 * x];   // blue 
      ptrOutput[4 * x + 1] = ptrInput[4 * x + 1]; // green 
      ptrOutput[4 * x + 2] = ptrInput[4 * x + 2]; // red 
      ptrOutput[4 * x + 3] = ptrMask[4 * x];  // alpha 
     } 
    } 
} 
mask.UnlockBits(bitsMask); 
input.UnlockBits(bitsInput); 
output.UnlockBits(bitsOutput); 

output.Save(...); 

यह उदाहरण मुखौटा छवि में नीले चैनल से उत्पादन में अल्फ़ा चैनल निकला । मुझे यकीन है कि यदि आवश्यक हो तो आप मास्क के लाल या अल्फा चैनल का उपयोग करने के लिए इसे बदल सकते हैं।

+0

मुझे अभी भी पिक्सेल को फिर से चालू करना होगा, है ना? – Origamiguy

+0

हां, लेकिन यह बहुत तेज़ है। कोई भी अन्य कार्यान्वयन जिसे आप संभावित रूप से उपयोग कर सकते हैं, को समान रूप से पिक्सेल के माध्यम से पुनरावृत्ति करना होगा। – Timwi

+0

अच्छा, यह काम करता है, और यह मेरी पिछली विधि से निश्चित रूप से तेज़ है, धन्यवाद! – Origamiguy

3

अपनी आवश्यकताओं पर निर्भर करता है यह बहुत आसान हो सकता है:

  • अपने मुखौटे उल्टें ताकि चक्र पारदर्शी है और बाकी एक रंग से (लाल की तरह अपने उदाहरण में) अपने इनपुट बिटमैप में इस्तेमाल नहीं किया है
  • अपनी छवि का उपयोग कर के शीर्ष पर अपने मुखौटा ड्रा Graphics.FromImage (छवि) .DrawImage (मुखौटा) ...
  • अपनी छवि पर मुखौटा रंग के रूप में पारदर्शी सेट (image.MakeTransparent (Color.Red))

इस विधि का एकमात्र दोष यह है कि यह सुनिश्चित करने के लिए कि आपको अपनी छवि में मास्क रंग का उपयोग नहीं किया जाता है। मुझे नहीं पता कि यह मैन्युअल तरीके से धीमा या तेज़ है या नहीं।

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