十万火急:请大侠们帮助,黑白bmp文件转为单色bmp文件?

.Net技术 码拜 6年前 (2015-05-10) 691次浏览 0个评论
 

因为在做小票打印机的项目,遇到一个困难。小票打印机只支持单色bmp图片的打印。
现在问题将一张黑白bmp图片转为单色bmp文件。在网上也找了很多资料,但都没有好的代码。
希望大拿们能帮忙解决一下。十万火急。多谢各位。以下有一段代码,但生成的结果不清楚。
供大家参考一下。另外提供一张源图。开发语言为c#。
另外我用系统自带的画图软件转换为单色bmp可以实现,但需要程序进行自动处理。
有没有大侠写段代码调用画图软件自动转换一下。
    private void button8_Click(object sender, EventArgs e)
    {
        int v = 8;
        Bitmap matrix = (Bitmap)Image.FromFile(“e:\m1_1.bmp”);        
        int width = matrix.Width;
        int height = matrix.Height;
        Bitmap bmp = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format1bppIndexed);
        Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
        System.Drawing.Imaging.BitmapData bmpData = bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, bmp.PixelFormat);

        IntPtr ptr = bmpData.Scan0;

        int sWidth = Math.Abs(bmpData.Stride);
        int sDepth = 8;
        int bytes = sWidth * bmp.Height;
        System.Diagnostics.Debug.WriteLine(string.Format(“宽度:{0},1个字符等于{1}像素”, sWidth, sDepth));
        System.Diagnostics.Debug.WriteLine(string.Format(“文件大小:{0}”, bytes));
        byte[] rgbValues = new byte[bytes];
        int r, g, b;
        int sColor = 0;
        System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);
        for (int h = 0; h < bmp.Height; h++)
        {
            for (int w = 0; w < sWidth; w++)
            {
                sColor = 0;
                for (int i = 0; i < sDepth; i++)
                {
                    if ((i + w * sDepth) >= bmp.Width)
                    {
                        break;
                    }
                    r = matrix.GetPixel(i + w * sDepth, h).R;
                    g = matrix.GetPixel(i + w * sDepth, h).G;
                    b = matrix.GetPixel(i + w * sDepth, h).B;
                    sColor += (byte)(((byte)(0.2125 * r + 0.7154 * g + 0.0721 * b) >= v) ? (128 >> (i)) : 0);
                }
                rgbValues[sWidth * h + w] = (byte)sColor;
            }
        }
        System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);
        bmp.UnlockBits(bmpData);
        bmp.Save(“e:\test.bmp”, System.Drawing.Imaging.ImageFormat.Bmp);
}

十万火急:请大侠们帮助,黑白bmp文件转为单色bmp文件?

源图在我的上传资源里也有,有需要的进行下载。多谢。
//二值化有很多算法,我没有去研究。步骤如下:
 
//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);
        }
多谢这位兄弟的回复。
我将代码测试了一下。转换后的结果还是不清楚。有很多都丢失了。
方便的话能不能麻烦你测试一下看看结果。万分感谢。

引用 2 楼 eit520 的回复:

C# code
?

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081

//二值化有很多算法,我没有去研究。步骤如下:  ……

多谢这位兄弟的回复。
我将代码测试了一下。转换后的结果还是不清楚。有很多都丢失了。
方便的话能不能麻烦你测试一下看看结果。万分感谢。

晕死!

你到底是要把图片弄模糊?还是改成某个颜色?

楼上贴出的代码都是把图片弄模糊的。将一个点周围多个点的颜色去平均值,这就是把它弄模糊。

我还是不太明白你说的“现在问题将一张黑白bmp图片转为单色bmp文件”是什么意思。如果原来是一个点的颜色黑色的(#000000),你把它改成蓝色(#0000FF)不就行了,只需要修改一个字节。你的代码中的 sColor 计算得又加权有平均地,是干什么呢?

引用 4 楼 red_fish 的回复:

引用 2 楼 eit520 的回复:C# code
?

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980……

那个160的阀值,你设为200看看。

十万火急:请大侠们帮助,黑白bmp文件转为单色bmp文件?
这是我弄出来的效果咯。。不知道是否可以满足?
5分
不管阀值为几,lz也没有需要像程序中那样“先变为模糊图形再二值化(黑白化)”。因此“各个点想加,然后除以9”完全是错误的。

另外,lz本来就有一个黑白图,只不过是要逐点变为单色的彩色图。不是别的要求。

还是重写程序吧。

引用 8 楼 sp1234 的回复:

不管阀值为几,lz也没有需要像程序中那样“先变为模糊图形再二值化(黑白化)”。因此“各个点想加,然后除以9”完全是错误的。

另外,lz本来就有一个黑白图,只不过是要逐点变为单色的彩色图。不是别的要求。

还是重写程序吧。

我的要求里原图里有汉字或字符或图案,转换为单色图后也要清楚显示出来。

引用 6 楼 eit520 的回复:

引用 4 楼 red_fish 的回复:
引用 2 楼 eit520 的回复:C# code
?

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757……

160阀值,好象代码里没有啊?
你转换的很清楚啊。
方便的话能不能把代码压缩一下发我邮箱里。peter.fish@qq.com,多谢啊。期待。。。。

引用 7 楼 eit520 的回复:

这是我弄出来的效果咯。。不知道是否可以满足?

另外转换出来后另存的图象格式是256色的,不是单色。
bmpDest这个bmp怎么保存为单色bmp啊?

95分
已经发送。查收一下。我用的VS2012,如果你没有这么高的版本,你就把代码复制一样,你应该懂的。
引用 12 楼 eit520 的回复:

已经发送。查收一下。我用的VS2012,如果你没有这么高的版本,你就把代码复制一样,你应该懂的。

太感谢你了,非常完美。
虽然我是man,但我还是想说:爱死你了。
结帐给分。

引用 13 楼 red_fish 的回复:
Quote: 引用 12 楼 eit520 的回复:

已经发送。查收一下。我用的VS2012,如果你没有这么高的版本,你就把代码复制一样,你应该懂的。

太感谢你了,非常完美。
虽然我是man,但我还是想说:爱死你了。
结帐给分。

楼主,能不能给我们发一下啊


CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明十万火急:请大侠们帮助,黑白bmp文件转为单色bmp文件?
喜欢 (0)
[1034331897@qq.com]
分享 (0)

文章评论已关闭!