读取单色位图像素颜色

发布于 2024-07-14 05:11:24 字数 1850 浏览 8 评论 0原文

我不知道更好的标题,但我会描述这个问题。

我们使用的硬件具有显示图像的能力。 它可以显示分辨率为 64 x 256 的黑白图像。

问题是我们必须发送到设备的图像格式。 它不是标准位图格式,而是简单的数组 表示图像每个像素的字节。

0 = 黑色,1 = 白色。

因此,如果我们有一个大小为: 4 x 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);
}

这里有两个问题:

  1. 生成的位图不是单色的
  2. 生成的位图具有不同的二进制格式

所以我需要一种方法:

  1. 在 .NET 中生成单色位图
  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;
}

I don't know a better title, but I'll describe the problem.

A piece of hardware we use has the ability to display images.
It can display a black and white image with a resolution of 64 x 256.

The problem is the format of the image we have to send to the device.
It is not a standard bitmap format, but instead it is simply an array of
bytes representing each pixel of the image.

0 = black, 1 = white.

So if we had an image with the size: 4 x 4 the byte array might look something like:

1000 0100 0010 0001

And the image would look like:

Bitmap http://www.mediafire.com/imgbnc.php/6ee6a28148d0170708cb10ec7ce6512e4g.jpg

The problem is that we need to create this image by creating a monochrome bitmap
in C# and then convert it to the file format understood by the device.

For example, one might to display text on the device. In order to do so he would
have to create a bitmap and write text to it:

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);
}

There are 2 problems here:

  1. The generated bitmap isn't monochrome
  2. The generated bitmap has a different binary format

So I need a way to:

  1. Generate a monochrome bitmap in .NET
  2. Read the individual pixel colors for each pixel in the bitmap

I have found that you can set the pixel depth to 16, 24, or 32 bits, but haven't found monochrome and I have no idea how to read the pixel data.

Suggestions are welcome.

UPDATE: I cannot use Win32 PInvokes... has to be platform neutral!

FOLLOW UP: The following code works for me now. (Just in case anybody needs it)

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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

故事↓在人 2024-07-21 05:11:24

我会计算每个像素 a 的亮度,然后将其与某个阈值进行比较。

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;
  }
}

I'd compute the luminance of each pixel a then compare it to some threshold value.

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

Say the threshold value is 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;
  }
}
淡忘如思 2024-07-21 05:11:24

我不懂 C#。 可能有很多方法可以做到这一点。 这是一个简单的方法。

  1. 创建大小等于您的设备要求的空白黑色位图图像。 在其上绘制任何您想要绘制的内容,例如文本、图形等。

  2. 现在对图像进行阈值设置,即将图像像素低于强度值的像素设置为零,否则将其设置为零。 例如设置所有强度值> 0 到 1。

  3. 现在转换为您的设备所需的格式。 创建大小为 (64 * 256)/8 的字节数组。 将相应的位设置为 1,其中早期位图中相应的像素值为 1,否则将它们重置为 0。

编辑:步骤 3. 使用按位运算符设置位。

I don't know C#. There are possibly many ways to do it. Here is a simple way.

  1. Create a blank black bitmap image of size equal to your device requirement. Draw on it whatever you wish to draw like text, figures etc.

  2. Now threshold the image i.e. set the pixel of image below an intensity value to zero else set it to. e.g. set all intensity values > 0 to 1.

  3. Now convert to the format required by your device. Create a byte array of the size (64 * 256)/8. Set the corresponding bits to 1 where the corresponding pixel values in earlier bitmap are 1, else reset them to 0.

Edit: Step 3. Use bitwise operators to set the bits.

心凉 2024-07-21 05:11:24

您不应该使用位图的 GetPixel 方法将整个位图从一种格式转换为另一种格式! 这将是无效的。 相反,您应该使用 LockBits 方法来访问图像的副本缓冲区并将其转换为所需的格式。 我不完全确定是否将其转换为单色,但 PixelFormat 枚举中有 Format1bppIndexed 值可能会对您有所帮助。

You shouldn't use GetPixel method of your bitmap to convert entire bitmap from one format to another! This will be ineffective. Instead you should use LockBits method to get access to a copy of image buffer and convert it into desired format. I'm not completely sure about converting it to monochrome but there is Format1bppIndexed value in PixelFormat enumeration which may help you.

一场春暖 2024-07-21 05:11:24

您可以尝试在构造函数中提供像素格式:

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

当我在其他平台上绘制单色位图时,我有时会遇到
禁用抗锯齿或渲染的文本将不会显示:

graphics.SmoothingMode=SmoothingMode.None;

YMMV。

You may try to supply a pixelformat in the constructor:

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

When I did draw monochrome bitmaps on other platforms I sometimes had
to disable antialiasing or the rendered text would not show up:

graphics.SmoothingMode=SmoothingMode.None;

YMMV.

一江春梦 2024-07-21 05:11:24

位图有一个 GetPixel 方法,您可以使用。 这将允许您在位图上绘图,然后将其转换为您需要的格式。

Windows 窗体中的位图(即通过 Graphics.FromImage 访问)为 24 bpp(也许是 32?现在还为时过早,我真的忘记了)。 尽管如此,GetPixel 返回一个 Color 对象,因此位图的位深度并不重要。 我建议您这样编写代码:

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);
}

这个过程称为简单阈值处理。 这是脑死亡,但它可以作为第一个剪辑。

Bitmap has a GetPixel method that you can use. This will let you draw on the Bitmap and later convert it to the format that you need.

Bitmaps in Windows forms (ie, accessed through Graphics.FromImage) are 24 bpp (maybe 32? It's too early and I honestly forget). Nonetheless, GetPixel returns a Color object, so the bit depth of the bitmap is immaterial. I suggest you write your code like this:

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);
}

This process is called simple thresholding. It's braindead, but it will work as a first cut.

小情绪 2024-07-21 05:11:24

感谢上面的代码 - 我正在尝试将单色图像转换为 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?

thanks for the above code - I'm trying to convert a monochrome image into a 2d array where 1-black 0-white however I'm having some trouble - I used your code to load an 8x8 bmp image, and am outputting its contents to a textbox by using

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

however I get this as a result in the textbox:

225  231  231  231  231  129  255  

how do I get it so it's 0's and 1's?

山人契 2024-07-21 05:11:24

本章节有一些创建单色位图的代码。 SaveImage 示例是我们感兴趣的示例。

This chap has some code that creates a mono bitmap. The SaveImage sample is the one of interest.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文