سؤال

أنا لا أعرف عنوان أفضل ، ولكن سوف تصف المشكلة.

قطعة من الأجهزة التي نستخدمها لديه القدرة على عرض الصور.فإنه يمكن عرض صورة بالأبيض والأسود مع قرار من 64 × 256.

المشكلة هي شكل صورة يجب أن ترسل إلى الجهاز.ليس معيار تنسيق الصورة النقطية, ولكن بدلا من ذلك هو ببساطة مجموعة من بايت يمثل كل بكسل من الصورة.

0 = أسود 1 = الأبيض.

حتى إذا كان لدينا صورة مع حجم:4 × 4 صفيف بايت قد تبدو شيئا مثل:

1000 0100 0010 0001

والصورة تبدو مثل:

نقطية http://www.mediafire.com/imgbnc.php/6ee6a28148d0170708cb10ec7ce6512e4g.jpg

المشكلة هي أننا بحاجة إلى إنشاء هذه الصورة من خلال إنشاء نقطية أحادية اللون في C# ومن ثم تحويله إلى تنسيق ملف فهمها من قبل الجهاز.

على سبيل المثال ، يمكن للمرء أن عرض النص على الجهاز.من أجل القيام بذلك سيكون لديك لإنشاء صورة نقطية وكتابة النص على ذلك:

var bitmap = new Bitmap(256, 64);

using (var graphics = Graphics.FromImage(bitmap))
{
    graphics.DrawString("Hello World", new Font("Courier", 10, FontStyle.Regular), new SolidBrush(Color.White), 1, 1);
}

هناك 2 مشاكل هنا:

  1. ولدت نقطية ليست أحادية اللون
  2. ولدت نقطية مختلفة تنسيق ثنائي

لذلك أنا بحاجة إلى طريقة:

  1. إنشاء نقطية أحادية اللون في .صافي
  2. قراءة الفرد بكسل الألوان لكل بكسل في الصورة النقطية

لقد وجدت أنه يمكنك تعيين بكسل عمق 16 أو 24 أو 32 بت, ولكن لم يتم العثور على أحادية اللون و ليس لدي أي فكرة عن كيفية قراءة البيانات بكسل.

اقتراحات هي موضع ترحيب.

تحديث: أنا لا يمكن استخدام Win32 PInvokes...يجب أن تكون منصة محايدة!

متابعة: التعليمة البرمجية التالية يعمل بالنسبة لي الآن.(فقط في حالة أي شخص يحتاج إليها)

private static byte[] GetLedBytes(Bitmap bitmap)
{
    int threshold = 127;
    int index = 0;
    int dimensions = bitmap.Height * bitmap.Width;

    BitArray bits = new BitArray(dimensions);

    //Vertically
    for (int y = 0; y < bitmap.Height; y++)
    {
        //Horizontally
        for (int x = 0; x < bitmap.Width; x++)
        {
            Color c = bitmap.GetPixel(x, y);
            int luminance = (int)(c.R * 0.3 + c.G * 0.59 + c.B * 0.11);
            bits[index] = (luminance > threshold);
            index++;
        }
    }

    byte[] data = new byte[dimensions / 8];
    bits.CopyTo(data, 0);
    return data;
}
هل كانت مفيدة؟

المحلول

كنت احسب الإنارة من كل بكسل ثم مقارنتها مع قيمة الحد الأدنى.

y=0.3*R+0.59G*G+0.11*B

يقول عتبة القيمة 127:

const int threshold = 127;
Bitmap bm = { some source bitmap };

byte[,] buffer = new byte[64,256];

for(int y=0;y<bm.Height;y++)
{
  for(int x=0;x<bm.Width;x++)
  {
   Color c=source.GetPixel(x,y);
   int luminance = (int)(c.R*0.3 + c.G*0.59+ c.B*0.11);
   buffer[x,y] = (luminance  > 127) ? 1 : 0;
  }
}

نصائح أخرى

أنا لا أعرف C#.هناك ربما العديد من الطرق للقيام بذلك.هنا هو طريقة بسيطة.

  1. إنشاء سوداء فارغة صورة نقطية من حجم يساوي جهازك شرط.رسم على ذلك مهما كنت ترغب في رسم مثل النص والأرقام وما إلى ذلك.

  2. الآن عتبة صورة أيمجموعة بكسل من الصورة أدناه كثافة القيمة إلى صفر آخر تعيين.على سبيل المثالكل مجموعة قيم كثافة > 0 إلى 1.

  3. الآن تحويلها إلى الشكل المطلوب من قبل الجهاز.إنشاء صفيف بايت من حجم (64 * 256)/8.تعيين المقابلة بت 1 مكان المقابلة بكسل القيم في وقت سابق النقطية هي 1 و آخر تعيين إلى 0.

تحرير:الخطوة 3.استخدام المعامل مشغلي تعيين بت.

لا يجب استخدام أسلوب GetPixel من النقطية الخاصة بك لتحويل كامل نقطية من تنسيق واحد إلى آخر!هذه لن تكون فعالة.بدلا من ذلك يجب عليك استخدام LockBits طريقة الحصول على نسخة من صورة العازلة وتحويله إلى التنسيق المطلوب.أنا لست متأكدا تماما عن تحويلها إلى أحادية اللون ولكن هناك Format1bppIndexed قيمة في PixelFormat التعداد التي قد تساعدك.

يمكنك محاولة تقدم pixelformat في منشئ:

var bitmap = new Bitmap(256, 64, PixelFormat.Format1bppIndexed);

عندما فعلت رسم صور نقطية أحادية اللون على منصات أخرى أنا في بعض الأحيان قد لتعطيل الحواف أو جعل النص لا تظهر:

graphics.SmoothingMode=SmoothingMode.None;

YMMV.

نقطية لديه أسلوب GetPixel التي يمكنك استخدامها.هذا سوف تتيح لك رسم على الصورة النقطية في وقت لاحق تحويلها إلى الشكل الذي تحتاجه.

الصور النقطية في نماذج Windows (أي الوصول إليها من خلال الرسومات.FromImage) 24 bpp (ربما 32?انه من المبكر جدا وأنا بصراحة تنسى).ومع ذلك ، GetPixel يعود اللون كائن حتى عمق قليلا من الصورة النقطية هو غير مادي.أقترح عليك كتابة رمز مثل هذا:

MyBitmapFormat ToMyBitmap(Bitmap b)
{
    MyBitmapFormat mine = new MyBitmapFormat(b.Width, b.Height);

    for (int y=0; y < b.Height; y++) {
        for (int x=0; x < b.Width; x++) {
            mine.SetPixel(x, y, ColorIsBlackish(b.GetPixel(x, y)));
        }
    }
}

bool ColorIsBlackish(Color c)
{
    return Luminance(c) < 128; // 128 is midline
}

int Luminance(c)
{
    return (int)(0.299 * Color.Red + 0.587 * Color.Green + 0.114 * Color.Blue);
}

وتسمى هذه العملية بسيطة thresholding.انها جننتني ولكن سيكون العمل الأول قطع.

شكرا على رمز أعلاه - أحاول تحويل صورة أحادية اللون في مجموعة 2d حيث 1-الأسود 0-أبيض ومع ذلك لدي بعض المشاكل - لا تستخدم التعليمات البرمجية الخاصة بك لتحميل 8x8 bmp صورة, وأنا إخراج محتوياته إلى مربع نص باستخدام

myGrid =GetLedBytes(myBmp);
     for (int x = 1; x < 8; x++)
     {
         textBox1.Text = textBox1.Text + Convert.ToString(myGrid[x])+ "  ";
     }

ومع ذلك تحصل هذه نتيجة في مربع نص:

225  231  231  231  231  129  255  

كيف يمكنني الحصول على ذلك 0 و 1 ؟

هذا الفصل بعض التعليمات البرمجية التي تنشئ أحادية نقطية.على SaveImage عينة واحدة من الفائدة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top