因为在做小票打印机的项目,遇到一个困难。小票打印机只支持单色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,如果你没有这么高的版本,你就把代码复制一样,你应该懂的。
|
太感谢你了,非常完美。 |
|
楼主,能不能给我们发一下啊 |