C# 读取单色位图像素颜色
我不知道更好的标题,但我会描述这个问题 我们使用的一个硬件能够显示图像。 它可以显示分辨率为64 x 256的黑白图像 问题是我们必须发送到设备的图像格式。 它不是标准的位图格式,而是一个数组 表示图像的每个像素的字节 0=黑色,1=白色 因此,如果我们有一个大小为:4x4的图像,字节数组可能看起来像: 1000 0100 0010 0001 图像看起来像: 问题是我们需要通过创建单色位图来创建此图像 然后将其转换为设备能够理解的文件格式 例如,可能需要在设备上显示文本。为了做到这一点,他将 必须创建位图并向其写入文本:C# 读取单色位图像素颜色,c#,.net,graphics,drawing,bitmap,C#,.net,Graphics,Drawing,Bitmap,我不知道更好的标题,但我会描述这个问题 我们使用的一个硬件能够显示图像。 它可以显示分辨率为64 x 256的黑白图像 问题是我们必须发送到设备的图像格式。 它不是标准的位图格式,而是一个数组 表示图像的每个像素的字节 0=黑色,1=白色 因此,如果我们有一个大小为:4x4的图像,字节数组可能看起来像: 1000 0100 0010 0001 图像看起来像: 问题是我们需要通过创建单色位图来创建此图像 然后将其转换为设备能够理解的文件格式 例如,可能需要在设备上显示文本。为了做到这一点,他将
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);
}
这里有两个问题:
private static byte[]GetLedBytes(位图)
{
int阈值=127;
int指数=0;
int-dimensions=位图.Height*位图.Width;
位数组位=新的位数组(维度);
//垂直的
对于(int y=0;y阈值);
索引++;
}
}
字节[]数据=新字节[尺寸/8];
位。复制到(数据,0);
返回数据;
}
有一些创建单声道位图的代码。SaveImage示例是一个有趣的示例。我不知道C。可能有很多方法可以做到这一点。这里有一个简单的方法
编辑:第3步。使用逐位运算符设置位。我会计算每个像素的亮度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;
}
}
const int threshold=127;
位图bm={some source Bitmap};
字节[,]缓冲区=新字节[64256];
对于(int y=0;y您不应该使用位图的GetPixel方法将整个位图从一种格式转换为另一种格式!这将无效。相反,您应该使用该方法访问图像缓冲区的副本并将其转换为所需格式。我不完全确定是否将其转换为单色,但Pix中有Format1Bppined值elFormat枚举,这可能会对您有所帮助。您可以尝试在构造函数中提供像素格式:
var bitmap = new Bitmap(256, 64, PixelFormat.Format1bppIndexed);
当我在其他平台上绘制单色位图时,我有时会
要禁用抗锯齿或渲染文本将不显示,请执行以下操作:
graphics.SmoothingMode=SmoothingMode.None;
YMMV.您可以使用。这将允许您在位图上绘制,然后将其转换为所需的格式
Windows窗体中的位图(即通过Graphics.FromImage访问)为24 bpp(可能是32 bpp?这太早了,我真的忘了)。尽管如此,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);
}
MyBitmapFormat ToMyBitmap(位图b)
{
MyBitmapFormat mine=新的MyBitmapFormat(b.宽度,b.高度);
对于(int y=0;y
这个过程被称为简单阈值。这是一个死脑筋的过程,但它可以作为第一次剪切。感谢上面的代码-我正在尝试将单色图像转换为二维数组,其中1-黑色0-白色,但我遇到了一些麻烦-我使用您的代码加载8x8 bmp图像,并使用
myGrid =GetLedBytes(myBmp);
for (int x = 1; x < 8; x++)
{
textBox1.Text = textBox1.Text + Convert.ToString(myGrid[x])+ " ";
}
如何获得0和1?问题是我不知道如何读取位图的像素值,需要检查API。必须有一些方法,如getPixel()、getIntensity()或者甚至一个简单的数组引用也可以。这一点很重要!但是如果您使用Bitmap.LockBits而不是Bitmap.GetPixel,您将获得更高的性能!Thnx!只需稍作调整,此代码就像一个符咒:-)danbystrom:你说得对,你想让示例代码尽可能干净,指针尽可能少。你不能在小于32bppil的任何地方调用Graphics.frommage如果你使用pixel.GetColor,你可以从一个像素获得RGB值,对吗?所以既然你在做黑白,你需要做的就是检查RGAN B==0,这意味着黑色。所有其他代码这是不需要的。
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