2009-02-01 16 views
7

मैं सी # प्रबंधित जीडीआई + लाइब्रेरी से सी # बिटमैप के किनारे व्हाइटसाइट का पता लगाने के लिए एक समाधान की तलाश में हूं।सी # जीडीआई एज व्हाइटस्पेस डिटेक्शन एल्गोरिदम

छवियों या तो पारदर्शी या सफेद, 400x चित्रों का सबसे किनारों के आसपास 2000px के बारे में सफेद स्थान के साथ 8000x8000px हैं होगा।

किनारों को खोजने का सबसे प्रभावी तरीका क्या होगा, x, y, ऊंचाई और चौड़ाई निर्देशांक? मैंने पिक्सेल द्वारा पिक्सेल जाने की कोशिश की लेकिन इसे बहुत धीमा लग रहा था।

समाधान के लिए अद्यतन --Added बाईं/सही/ऊपर/नीचे सीमा

छवियों विस्तार केंद्र छवियों के साथ कोई समस्या है, अब किसी भी पारदर्शी (0%) सफेद (#FFFFFF) पिक्सल फसलों या।

var top = bitmap.Height; 
var left = bitmap.Width; 
var right = 0; 
var bottom = 0; 

...

var pData = pData0 + (y * data.Stride) + (x * 4); 
var xyAlpha = pData[3]; 
var xyBlue = pData[0]; 
var xyGreen = pData[1]; 
var xyRed = pData[2]; 
if ((xyAlpha > 0) || (xyRed != 255 && xyGreen != 255 && xyBlue != 255)) { 
    if (y < top) 
     top = y; 
    if (y > bottom) 
     bottom = y; 
    if (x < left) 
     left = x; 
    if (x > right) 
     right = x; 
} 

...

var cropWidth = right - left; 
var cropHeight = bottom - top; 
var cropX = top; 
var cropY = left; 

var cacheBitmap = new Bitmap(cropWidth, cropHeight, PixelFormat.Format32bppArgb); 
using (var cacheGraphics = Graphics.FromImage(cacheBitmap)) { 
    cacheGraphics.DrawImage(context.Image, new Rectangle(0, 0, cropWidth, cropHeight), cropX, cropY, cropWidth, cropHeight, GraphicsUnit.Pixel); 
} 

उत्तर

9

एक महान GDI + संसाधन Bob Powells GDI+ FAQ है!

आपने यह नहीं कहा कि आपने छवि में पिक्सल का उपयोग कैसे किया है, इसलिए मुझे लगता है कि आपने धीमे GetPixel विधियों का उपयोग किया था। आप एक तेजी से रास्ते में पिक्सल का उपयोग करने के संकेत दिए गए और LockBits उपयोग कर सकते हैं: see Bob Powells explanation of LockBits - यह एक असुरक्षित कोड ब्लॉक की आवश्यकता होगी - अगर आप यह नहीं चाहता है या आप की जरूरत नहीं है FullTrust आप उपयोग कर सकते हैं चाल यहां विस्तार से बताया: Pointerless Image Processing in .NET by J. Dunlap

नीचे दिया गया कोड लॉकबिट्स दृष्टिकोण (PixelFormat.Format32bppArgb के लिए) का उपयोग करता है और उस मान के साथ प्रारंभ और अंत बिंदु को भर देगा जहां किसी छवि में पहले और आखिरी पिक्सेल की खोज की जाती है जिसमें तर्क रंग में वर्णित रंग नहीं होता है। विधि पूरी तरह से पारदर्शी पिक्सल को भी अनदेखा करती है जो उपयोगी है यदि आप किसी छवि के क्षेत्र का पता लगाना चाहते हैं जहां दृश्यमान 'सामग्री' शुरू होती है।

Point start = Point.Empty; 
    Point end = Point.Empty; 

    int bitmapWidth = bmp.Width; 
    int bitmapHeight = bmp.Height; 

    #region find start and end point 
    BitmapData data = bmp.LockBits(new Rectangle(0, 0, bitmapWidth, bitmapHeight), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); 
    try 
    { 
     unsafe 
     { 
      byte* pData0 = (byte*)data.Scan0; 
      for (int y = 0; y < bitmapHeight; y++) 
      { 
       for (int x = 0; x < bitmapWidth; x++) 
       { 
        byte* pData = pData0 + (y * data.Stride) + (x * 4); 

        byte xyBlue = pData[0]; 
        byte xyGreen = pData[1]; 
        byte xyRed = pData[2]; 
        byte xyAlpha = pData[3]; 


        if (color.A != xyAlpha 
          || color.B != xyBlue 
          || color.R != xyRed 
          || color.G != xyGreen) 
        { 
         //ignore transparent pixels 
         if (xyAlpha == 0) 
          continue; 
         if (start.IsEmpty) 
         { 
          start = new Point(x, y); 
         } 
         else if (start.Y > y) 
         { 
          start.Y = y; 
         } 
         if (end.IsEmpty) 
         { 
          end = new Point(x, y); 
         } 
         else if (end.X < x) 
         { 
          end.X = x; 
         } 
         else if (end.Y < y) 
         { 
          end.Y = y; 
         } 
        } 
       } 
      } 
     } 
    } 
    finally 
    { 
     bmp.UnlockBits(data); 
    } 
    #endregion 
2

मैं पहले पैट्रिक द्वारा वर्णित लॉकबिट विधि का उपयोग करना सुनिश्चित करता हूं। दूसरा मैं किनारों को जल्दी से निर्धारित करने के लिए मध्य रेखाओं पर पिक्सेल की जांच करता हूं। मध्य रेखाओं से मेरा मतलब है, यदि आपने उदाहरण के लिए 2000x1000 छवि कहा है, तो आप बाएं और दाएं सीमाओं को खोजने के लिए क्षैतिज रेखा संख्या 500 (1000 में से) के साथ पहले देखेंगे, फिर लंबवत रेखा संख्या 1000 (2000 में से) ऊपर और नीचे सीमा खोजने के लिए। यह इस तरह से बहुत तेज होना चाहिए।

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