|
因为在做小票打印机的项目,遇到一个困难。小票打印机只支持单色bmp图片的打印。 IntPtr ptr = bmpData.Scan0; int sWidth = Math.Abs(bmpData.Stride);
|
|
|
源图在我的上传资源里也有,有需要的进行下载。多谢。
|
|
//二值化有很多算法,我没有去研究。步骤如下:
//1. 首先灰度化,简单把三色相加除以3
//2. 二值化,将一个点周围8个点全部相加,除以9 ,然后根据一个阀值决定是黑还是白,我用160
//3. 一定要用LockBit,直接处理图像数据,速度才能快
//代码如下:
int n = 3;
/// <summary>
/// 转化普通图像到2值图像
/// </summary>
/// <param name="bmp"></param>
/// <returns></returns>
Bitmap ConvertImageTo2Value(Bitmap bmp)
{
int w = bmp.Width;
int h = bmp.Height;
BitmapData data = bmp.LockBits(new Rectangle(0, 0, w, h),
ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
unsafe
{
// 将原始图片变成灰度二位数组
byte* p = (byte*)data.Scan0;
byte[,] vSource = new byte[w, h];
int offset = data.Stride - w * n;
for (int y = 0; y < h; y++)
{
for (int x = 0; x < w; x++)
{
vSource[x, y] = (byte)(((int)p[0] + (int)p[1] + (int)p[2]) / 3);
p += n;
}
p += offset;
}
bmp.UnlockBits(data);
// 将灰度二位数组变成二值图像
Bitmap bmpDest = new Bitmap(w, h, PixelFormat.Format24bppRgb);
BitmapData dataDest = bmpDest.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.WriteOnly,
PixelFormat.Format24bppRgb);
p = (byte*)dataDest.Scan0;
offset = dataDest.Stride - w * n;
for (int y = 0; y < h; y++)
{
for (int x = 0; x < w; x++)
{
//p[0] = p[1] = p[2] = (int)vSource[x, y] > 160 ? (byte)255 : (byte)0;
p[0] = p[1] = p[2] = (int)GetAverageColor(vSource, x, y, w, h) > 120 ? (byte)255 : (byte)0;
p += n;
}
p += offset;
}
bmpDest.UnlockBits(dataDest);
// return
return bmpDest;
}
}
byte GetAverageColor(byte[,] vSource, int x, int y, int w, int h)
{
int rs = vSource[x, y]
+ (x == 0 ? 255 : (int)vSource[x - 1, y])
+ (x == 0 || y == 0 ? 255 : (int)vSource[x - 1, y - 1])
+ (x == 0 || y == h - 1 ? 255 : (int)vSource[x - 1, y + 1])
+ (y == 0 ? 255 : (int)vSource[x, y - 1])
+ (y == h - 1 ? 255 : (int)vSource[x, y + 1])
+ (x == w - 1 ? 255 : (int)vSource[x + 1, y])
+ (x == w - 1 || y == 0 ? 255 : (int)vSource[x + 1, y - 1])
+ (x == w - 1 || y == h - 1 ? 255 : (int)vSource[x + 1, y + 1]);
return (byte)(rs / 9);
}
|
|
|
多谢这位兄弟的回复。
我将代码测试了一下。转换后的结果还是不清楚。有很多都丢失了。 方便的话能不能麻烦你测试一下看看结果。万分感谢。 |
|
|
多谢这位兄弟的回复。 |
|
|
晕死!
你到底是要把图片弄模糊?还是改成某个颜色? 楼上贴出的代码都是把图片弄模糊的。将一个点周围多个点的颜色去平均值,这就是把它弄模糊。 我还是不太明白你说的“现在问题将一张黑白bmp图片转为单色bmp文件”是什么意思。如果原来是一个点的颜色黑色的(#000000),你把它改成蓝色(#0000FF)不就行了,只需要修改一个字节。你的代码中的 sColor 计算得又加权有平均地,是干什么呢? |
|
|
那个160的阀值,你设为200看看。 |
|
![]() 这是我弄出来的效果咯。。不知道是否可以满足? |
|
| 5分 |
不管阀值为几,lz也没有需要像程序中那样“先变为模糊图形再二值化(黑白化)”。因此“各个点想加,然后除以9”完全是错误的。
另外,lz本来就有一个黑白图,只不过是要逐点变为单色的彩色图。不是别的要求。 还是重写程序吧。 |
|
我的要求里原图里有汉字或字符或图案,转换为单色图后也要清楚显示出来。 |
|
|
160阀值,好象代码里没有啊? |
|
|
另外转换出来后另存的图象格式是256色的,不是单色。 |
|
| 95分 |
已经发送。查收一下。我用的VS2012,如果你没有这么高的版本,你就把代码复制一样,你应该懂的。
|
|
太感谢你了,非常完美。 |
|
|
楼主,能不能给我们发一下啊 |
|

