2010-02-15 13 views
46

पर कनवर्ट करें क्या कोई छवि आर, जी और बी घटकों को चमकने के बजाय, ग्रेस्केल 16 पिक्सल प्रति बिट प्रारूप में कनवर्ट करने का कोई तरीका है। मैं वर्तमान में फ़ाइल से एक बीएमपी है।एक छवि को ग्रेस्केल

Bitmap c = new Bitmap("filename"); 

मुझे एक बिटमैप डी चाहिए, जो सी का ग्रेस्केल संस्करण है। मुझे एक कन्स्ट्रक्टर दिखाई देता है जिसमें System.Drawing.Imaging.PixelFormat शामिल है, लेकिन मुझे समझ में नहीं आता कि इसका उपयोग कैसे किया जाए। मैं छवि प्रसंस्करण और प्रासंगिक सी # पुस्तकालयों के लिए नया हूं, लेकिन सी # के साथ एक मामूली अनुभव है।

किसी भी मदद, किसी ऑनलाइन स्रोत, संकेत या सुझाव के संदर्भ में सराहना की जाएगी।

धन्यवाद।

संपादित करें: डी सी का ग्रेस्केल संस्करण है।

उत्तर

56

"मैं चाहता हूँ एक बिटमैप घ, कि ग्रेस्केल है। मैं एक consructor कि System.Drawing.Imaging.PixelFormat, शामिल क्यों दिखाई देता है, लेकिन मुझे समझ नहीं आता कि का उपयोग कैसे करें।"

public static Bitmap MakeGrayscale3(Bitmap original) 
{ 
    //create a blank bitmap the same size as original 
    Bitmap newBitmap = new Bitmap(original.Width, original.Height); 

    //get a graphics object from the new image 
    Graphics g = Graphics.FromImage(newBitmap); 

    //create the grayscale ColorMatrix 
    ColorMatrix colorMatrix = new ColorMatrix(
     new float[][] 
     { 
     new float[] {.3f, .3f, .3f, 0, 0}, 
     new float[] {.59f, .59f, .59f, 0, 0}, 
     new float[] {.11f, .11f, .11f, 0, 0}, 
     new float[] {0, 0, 0, 1, 0}, 
     new float[] {0, 0, 0, 0, 1} 
     }); 

    //create some image attributes 
    ImageAttributes attributes = new ImageAttributes(); 

    //set the color matrix attribute 
    attributes.SetColorMatrix(colorMatrix); 

    //draw the original image on the new image 
    //using the grayscale color matrix 
    g.DrawImage(original, new Rectangle(0, 0, original.Width, original.Height), 
     0, 0, original.Width, original.Height, GraphicsUnit.Pixel, attributes); 

    //dispose the Graphics object 
    g.Dispose(); 
    return newBitmap; 
} 
: पूर्ण विश्लेषण के लिए switchonthecode कड़ी का अनुसरण से ग्रेस्केल में बदलने के लिए

   Bitmap c = new Bitmap("fromFile"); 
      Bitmap d; 
      int x, y; 

      // Loop through the images pixels to reset color. 
      for (x = 0; x < c.Width; x++) 
      { 
       for (y = 0; y < c.Height; y++) 
       { 
        Color pixelColor = c.GetPixel(x, y); 
        Color newColor = Color.FromArgb(pixelColor.R, 0, 0); 
        c.SetPixel(x, y, newColor); // Now greyscale 
       } 
      } 
      d = c; // d is grayscale version of c 

तेज़ संस्करण:

यहां इस

Bitmap grayScaleBP = new 
     System.Drawing.Bitmap(2, 2, System.Drawing.Imaging.PixelFormat.Format16bppGrayScale); 

संपादित करने के लिए है

+0

मुझे खेद है, मुझे यह कहना चाहिए था कि मेरे प्रश्न में कि मैं अपने मूल बिटमैप के ग्रेस्केल संस्करण को चाहता हूं, मैंने इसे प्रतिबिंबित करने के लिए पोस्ट संपादित किया है। – 0fnt

+11

यह विधि (पिक्सेल द्वारा पिक्सेल बहुत धीमी है) इस आलेख को यहां देखें: http: //www.switchonthecode.com/tutorials/csharp-tutorial-convert-a-color-image-to-grayscale – Luis

+6

इसके अलावा, पिक्सेल-बाय -पिक्सेल विधि केवल लाल मान का उपयोग कर रहा था .... – mpen

27
Bitmap d = new Bitmap(c.Width, c.Height); 

for (int i = 0; i < c.Width; i++) 
{ 
    for (int x = 0; x < c.Height; x++) 
    { 
     Color oc = c.GetPixel(i, x); 
     int grayScale = (int)((oc.R * 0.3) + (oc.G * 0.59) + (oc.B * 0.11)); 
     Color nc = Color.FromArgb(oc.A, grayScale, grayScale, grayScale); 
     d.SetPixel(i, x, nc); 
    } 
} 

इस तरह यह अल्फा चैनल भी रखता है।
आनंद लें।

+4

मुझे डाउनवोट क्यों मिला? यह जवाब बिल्कुल ठीक है और विषय पर है। – Vercas

+1

मुझे पता है कि यह एक पुराना उत्तर है, लेकिन क्या आप उन स्थिरांकों पर विस्तार कर सकते हैं जिन्हें आप आर, जी, बी मानों पर गुणा करते हैं? मुझे लगता है कि यह "1.0" तक है, लेकिन क्या कोई स्पष्टीकरण है? –

+3

@LarsKristensen इसे देखें: https://en.wikipedia.org/wiki/Grayscale – lukegravitt

6

ऊपर दिए गए उदाहरणों में से कोई भी 8-बिट (8bpp) बिटमैप छवियां नहीं बनाते हैं। कुछ सॉफ्टवेयर, जैसे छवि प्रसंस्करण, केवल 8bpp का समर्थन करता है। दुर्भाग्य से एमएस .NET पुस्तकालयों में कोई समाधान नहीं है। PixelFormat.Format8bppIndexed प्रारूप वादा करता है लेकिन कई प्रयासों के बाद मैं इसे काम नहीं कर सका।

एक वास्तविक 8-बिट बिटमैप फ़ाइल बनाने के लिए आपको proper headers बनाने की आवश्यकता है। आखिरकार मुझे 8-बिट बिटमैप (बीएमपी) फाइलें बनाने के लिए Grayscale library समाधान मिला। कोड बहुत सरल है:

Image image = Image.FromFile("c:/path/to/image.jpg"); 
GrayBMP_File.CreateGrayBitmapFile(image, "c:/path/to/8bpp/image.bmp"); 

इस परियोजना के लिए कोड बहुत से दूर है, लेकिन यह एक छोटे से सरल करने के लिए ठीक समस्या के साथ, काम करता है। लेखक ने छवि संकल्प को 10x10 तक हार्ड-कोड किया। छवि प्रसंस्करण कार्यक्रम इसे पसंद नहीं करते हैं। फिक्स खुला है GayBMP_File.cs (हाँ, फंकी फ़ाइल नामकरण, मुझे पता है) और नीचे दिए गए कोड के साथ लाइन 50 और 51 को प्रतिस्थापित करें। उदाहरण संकल्प को 200x200 पर सेट करता है लेकिन आपको इसे उचित संख्या में बदलना चाहिए।

int resX = 200; 
int resY = 200; 
// horizontal resolution 
Copy_to_Index(DIB_header, BitConverter.GetBytes(resX * 100), 24); 
// vertical resolution 
Copy_to_Index(DIB_header, BitConverter.GetBytes(resY * 100), 28); 
+0

मैं इसे जांचना और ऊपर उठाना चाहता हूं, लेकिन अभी समय पर छोटा हूं। हालांकि उत्तर के लिए धन्यवाद। – 0fnt

+0

8bpp के साथ चाल यह है कि आपको छवि का समर्थन करने वाले कच्चे आंतरिक सरणी को संपादित करने की आवश्यकता है। आप 'image.LockBits()' को कॉल करके और फिर 'मार्शल.कोपी' का उपयोग करके डेटा को कॉपी/आउट करके प्राप्त कर सकते हैं। Google को पूरी प्रक्रिया प्राप्त करने के लिए। एक छवि के किनारे (डेटा से पढ़ी गई रेखा) अक्सर ध्यान दें, वास्तविक चौड़ाई की तुलना में अक्सर लंबी होती है, क्योंकि यह 4 बाइट्स के नजदीकी एकाधिक से घिरा हुआ है। – Nyerguds

6

यहाँ कुछ आइटम संक्षेप में: कुछ पिक्सेल द्वारा पिक्सेल विकल्प है, जबकि सरल किया जा रहा है सिर्फ तेजी से नहीं कर रहे हैं।

@Luis 'टिप्पणी से लिंक: (संग्रहित) https://web.archive.org/web/20110827032809/http://www.switchonthecode.com/tutorials/csharp-tutorial-convert-a-color-image-to-grayscale शानदार है।

वह तीन अलग-अलग विकल्पों के माध्यम से चलता है और प्रत्येक के लिए समय शामिल करता है।

Bitmap bt = new Bitmap("imageFilePath"); 

for (int y = 0; y < bt.Height; y++) 
{ 
    for (int x = 0; x < bt.Width; x++) 
    { 
     Color c = bt.GetPixel(x, y); 

     int r = c.R; 
     int g = c.G; 
     int b = c.B; 
     int avg = (r + g + b)/3; 
     bt.SetPixel(x, y, Color.FromArgb(avg,avg,avg)); 
    } 
} 

bt.Save("d:\\out.bmp"); 
+3

उपरोक्त लिंक में तीसरा उदाहरण सुपर कुशल है और मेरी समस्या का समाधान सीधे – ford

+0

दुख की बात है कि लिंक अब मर चुका है ... –

+3

@ रिचर्डएवरेट वास्तव में। बचाव के लिए वेब संग्रह! फिक्स्ड। – jeffreypriebe

3

नीचे कोड सरल समाधान है। इसका उपयोग के रूप में सरल है:

Bitmap c = new Bitmap("filename"); 
Image d = ToolStripRenderer.CreateDisabledImage(c); 

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

9

ToolStripRenderer कक्षा में एक स्थिर विधि, CreateDisabledImage नामित नहीं है:

+2

ओह मैन, इसके लिए धन्यवाद। यह WinForms में अक्षम नियंत्रणों के भीतर छवियों के रूप से मेल खाता है, जो सबकुछ सुसंगत दिखता रहता है। – Jimmy

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