यहां कुछ कोड है जो मैंने एक साथ रखा है जो एक पूर्ण रंग (24 बिट/पिक्सेल) छवि लेता है, और इसे 1 बिट/पिक्सेल आउटपुट बिटमैप में परिवर्तित करता है, एक मानक आरजीबी को ग्रेस्केल रूपांतरण में लागू करता है, और फिर फ़्लॉइड-स्टीनबर्ग का उपयोग करता है ग्रेस्केल को 1 बिट/पिक्सेल आउटपुट में कनवर्ट करें।
ध्यान दें कि इसे किसी भी "आदर्श" कार्यान्वयन के रूप में नहीं माना जाना चाहिए, लेकिन यह काम करता है। यदि आप चाहते थे तो कई सुधार किए जा सकते हैं। उदाहरण के लिए, यह पूरे इनपुट छवि को data
सरणी में प्रतिलिपि बनाता है, जबकि हमें वास्तव में त्रुटि डेटा जमा करने के लिए केवल दो पंक्तियों को स्मृति ("वर्तमान" और "अगली" पंक्तियां) रखने की आवश्यकता होती है। इसके बावजूद, प्रदर्शन स्वीकार्य लगता है।
public static Bitmap ConvertTo1Bit(Bitmap input)
{
var masks = new byte[] { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
var output = new Bitmap(input.Width, input.Height, PixelFormat.Format1bppIndexed);
var data = new sbyte[input.Width, input.Height];
var inputData = input.LockBits(new Rectangle(0, 0, input.Width, input.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
try
{
var scanLine = inputData.Scan0;
var line = new byte[inputData.Stride];
for (var y = 0; y < inputData.Height; y++, scanLine += inputData.Stride)
{
Marshal.Copy(scanLine, line, 0, line.Length);
for (var x = 0; x < input.Width; x++)
{
data[x, y] = (sbyte)(64 * (GetGreyLevel(line[x * 3 + 2], line[x * 3 + 1], line[x * 3 + 0]) - 0.5));
}
}
}
finally
{
input.UnlockBits(inputData);
}
var outputData = output.LockBits(new Rectangle(0, 0, output.Width, output.Height), ImageLockMode.WriteOnly, PixelFormat.Format1bppIndexed);
try
{
var scanLine = outputData.Scan0;
for (var y = 0; y < outputData.Height; y++, scanLine += outputData.Stride)
{
var line = new byte[outputData.Stride];
for (var x = 0; x < input.Width; x++)
{
var j = data[x, y] > 0;
if (j) line[x/8] |= masks[x % 8];
var error = (sbyte)(data[x, y] - (j ? 32 : -32));
if (x < input.Width - 1) data[x + 1, y] += (sbyte)(7 * error/16);
if (y < input.Height - 1)
{
if (x > 0) data[x - 1, y + 1] += (sbyte)(3 * error/16);
data[x, y + 1] += (sbyte)(5 * error/16);
if (x < input.Width - 1) data[x + 1, y + 1] += (sbyte)(1 * error/16);
}
}
Marshal.Copy(line, 0, scanLine, outputData.Stride);
}
}
finally
{
output.UnlockBits(outputData);
}
return output;
}
public static double GetGreyLevel(byte r, byte g, byte b)
{
return (r * 0.299 + g * 0.587 + b * 0.114)/255;
}
http://stackoverflow.com/questions/4669317/how-to-convert-a-bitmap-image-to-black-and-white-in-c – Dmitriy
की [काला करने के लिए छवि परिवर्तित संभव डुप्लिकेट -हाइट या सेपिया सी #] (http://stackoverflow.com/questions/4624998/convert-image-to-black-white-or-sepia-in-c-sharp) – ken2k
दरअसल, ऐसा लगता है कि ये प्रश्न हैं ग्रेस्केल में कनवर्ट करने के बारे में - जबकि ओपी इसे 1 बीपीपी मोनोक्रोम में परिवर्तित करना चाहता है, जिसमें थ्रेसहोल्डिंग/डाइटिंग शामिल है। – Ani