C# 读取单色位图像素颜色

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/601963/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 09:53:37  来源:igfitidea点击:

Reading monochrome bitmap pixel colors

c#.netgraphicsdrawingbitmap

提问by TimothyP

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.

我们使用的硬件具有显示图像的能力。它可以显示分辨率为 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.

0 = 黑色,1 = 白色。

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

因此,如果我们有一个大小为 4 x 4 的图像,则字节数组可能如下所示:

1000 0100 0010 0001

1000 0100 0010 0001

And the image would look like:

图像看起来像:

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

位图 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.

问题是我们需要通过在 C# 中创建单色位图来创建此图像,然后将其转换为设备可以理解的文件格式。

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:

这里有2个问题:

  1. The generated bitmap isn't monochrome
  2. The generated bitmap has a different binary format
  1. 生成的位图不是单色的
  2. 生成的位图具有不同的二进制格式

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
  1. 在 .NET 中生成单色位图
  2. 读取位图中每个像素的单个像素颜色

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.

我发现您可以将像素深度设置为 16、24 或 32 位,但还没有找到单色,我也不知道如何读取像素数据。

Suggestions are welcome.

欢迎提出建议。

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

更新:我不能使用 Win32 PInvokes...必须是平台中立的!

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

采纳答案by arul

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:

假设阈值为 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;
  }
}

回答by Quibblesome

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

这一章有一些创建单声道位图的代码。SaveImage 示例是令人感兴趣的示例。

回答by Xolve

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

我不知道 C#。可能有很多方法可以做到。这里有一个简单的方法。

  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.

  1. 创建大小等于您的设备要求的空白黑色位图图像。在上面画任何你想画的东西,比如文字、数字等。

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

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

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

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

回答by okutane

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 LockBitsmethod 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.

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

回答by okutane

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.

天啊。

回答by plinth

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

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

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:

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

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

这个过程称为简单阈值。它是脑残,但它可以作为第一次剪辑。

回答by user311225

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

感谢上面的代码 - 我正在尝试将单色图像转换为 2d 数组,其中 1-black 0-white 但是我遇到了一些麻烦 - 我使用您的代码加载了 8x8 bmp 图像,并正在输出其内容使用文本框

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?

我怎么得到它所以它是0和1?