问题描述
请教大神们怎么用C#存储单色位图,和画板生成的单色为图一样。用于打印机打印单色位图(热敏打印机只支持单色位图)求完整的代码。
解决方案
解决方案二:
解决方案三:
引用1楼starfd的回复:没有尝试过?这个代码要下载才可用使用。
解决方案四:
单色图?二值化?。publicImageGetBinaryImage(ImageimgSrc,bytebyValue){Bitmapb=newBitmap(imgSrc);Bitmapbmp=b.Clone(newRectangle(0,0,imgSrc.Width,imgSrc.Height),PixelFormat.Format24bppRgb);b.Dispose();BitmapDatabmpData=bmp.LockBits(newRectangle(0,0,bmp.Width,bmp.Height),ImageLockMode.ReadWrite,bmp.PixelFormat);byte[]byColorInfo=newbyte[bmp.Height*bmpData.Stride];Marshal.Copy(bmpData.Scan0,byColorInfo,0,byColorInfo.Length);bytebyR,byG,byB;for(intx=0,xLen=bmp.Width;x<xLen;x++){for(inty=0,yLen=bmp.Height;y<yLen;y++){byB=byColorInfo[y*bmpData.Stride+x*3];byG=byColorInfo[y*bmpData.Stride+x*3+1];byR=byColorInfo[y*bmpData.Stride+x*3+2];bytebyV=GetAvg(byR,byG,byB);if(byV>=byValue){byV=255;}else{byV=0;}byColorInfo[y*bmpData.Stride+x*3]=byColorInfo[y*bmpData.Stride+x*3+1]=byColorInfo[y*bmpData.Stride+x*3+2]=byV;}}Marshal.Copy(byColorInfo,0,bmpData.Scan0,byColorInfo.Length);bmp.UnlockBits(bmpData);returnbmp;}
解决方案五:
引用3楼crystal_lz的回复:
单色图?二值化?。publicImageGetBinaryImage(ImageimgSrc,bytebyValue){Bitmapb=newBitmap(imgSrc);Bitmapbmp=b.Clone(newRectangle(0,0,imgSrc.Width,imgSrc.Height),PixelFormat.Format24bppRgb);b.Dispose();BitmapDatabmpData=bmp.LockBits(newRectangle(0,0,bmp.Width,bmp.Height),ImageLockMode.ReadWrite,bmp.PixelFormat);byte[]byColorInfo=newbyte[bmp.Height*bmpData.Stride];Marshal.Copy(bmpData.Scan0,byColorInfo,0,byColorInfo.Length);bytebyR,byG,byB;for(intx=0,xLen=bmp.Width;x<xLen;x++){for(inty=0,yLen=bmp.Height;y<yLen;y++){byB=byColorInfo[y*bmpData.Stride+x*3];byG=byColorInfo[y*bmpData.Stride+x*3+1];byR=byColorInfo[y*bmpData.Stride+x*3+2];bytebyV=GetAvg(byR,byG,byB);if(byV>=byValue){byV=255;}else{byV=0;}byColorInfo[y*bmpData.Stride+x*3]=byColorInfo[y*bmpData.Stride+x*3+1]=byColorInfo[y*bmpData.Stride+x*3+2]=byV;}}Marshal.Copy(byColorInfo,0,bmpData.Scan0,byColorInfo.Length);bmp.UnlockBits(bmpData);returnbmp;}
单色位图啊!你的代码不完整。
解决方案六:
那个是不行的,已然是24位位图,只是将色彩变成灰色而已你要的是Format1bppIndexed格式的bmp待会如果我的代码能测试通过的话,就给你
解决方案七:
引用5楼xuzuning的回复:
那个是不行的,已然是24位位图,只是将色彩变成灰色而已你要的是Format1bppIndexed格式的bmp待会如果我的代码能测试通过的话,就给你
麻烦你了!我的邮箱是357901986@qq.com
解决方案八:
希望有人帮忙解决下!
解决方案九:
引用4楼u013416462的回复:
Quote: 引用3楼crystal_lz的回复:
单色图?二值化?。publicImageGetBinaryImage(ImageimgSrc,bytebyValue){Bitmapb=newBitmap(imgSrc);Bitmapbmp=b.Clone(newRectangle(0,0,imgSrc.Width,imgSrc.Height),PixelFormat.Format24bppRgb);b.Dispose();BitmapDatabmpData=bmp.LockBits(newRectangle(0,0,bmp.Width,bmp.Height),ImageLockMode.ReadWrite,bmp.PixelFormat);byte[]byColorInfo=newbyte[bmp.Height*bmpData.Stride];Marshal.Copy(bmpData.Scan0,byColorInfo,0,byColorInfo.Length);bytebyR,byG,byB;for(intx=0,xLen=bmp.Width;x<xLen;x++){for(inty=0,yLen=bmp.Height;y<yLen;y++){byB=byColorInfo[y*bmpData.Stride+x*3];byG=byColorInfo[y*bmpData.Stride+x*3+1];byR=byColorInfo[y*bmpData.Stride+x*3+2];bytebyV=GetAvg(byR,byG,byB);if(byV>=byValue){byV=255;}else{byV=0;}byColorInfo[y*bmpData.Stride+x*3]=byColorInfo[y*bmpData.Stride+x*3+1]=byColorInfo[y*bmpData.Stride+x*3+2]=byV;}}Marshal.Copy(byColorInfo,0,bmpData.Scan0,byColorInfo.Length);bmp.UnlockBits(bmpData);returnbmp;}单色位图啊!你的代码不完整。
不就是差了一个GetAvg么想也想得到这个函数是干嘛的以及是怎么写的
解决方案十:
你要的是这个效果吧?把左边的24位真彩,转成右边的单色位图privatestaticBitmapBuiltBlackWhiteBitmap(byte[]rawValues,intwidth,intheight){//新建一个8位灰度位图,并锁定内存区域操作Bitmapbitmap=newBitmap(width,height,PixelFormat.Format1bppIndexed);BitmapDatabmpData=bitmap.LockBits(newRectangle(0,0,width,height),ImageLockMode.WriteOnly,PixelFormat.Format1bppIndexed);//计算图像参数intoffset=bmpData.Stride-bmpData.Width/8;//计算每行未用空间字节数IntPtrptr=bmpData.Scan0;//获取首地址intscanBytes=bmpData.Stride*bmpData.Height;//图像字节数=扫描字节数*高度byte[]grayValues=newbyte[scanBytes];//为图像数据分配内存//为图像数据赋值intposSrc=0,posScan=0;//rawValues和grayValues的索引for(inti=0;i<height;i++){for(intj=0;j<width/8;j++){byteb=0;for(intk=0;k<8;k++)b=(byte)((b<<1)|(byte)(rawValues[posSrc++]<96?0:1));grayValues[posScan++]=b;}//跳过图像数据每行未用空间的字节,length=stride-width*bytePerPixelposScan+=offset;}//内存解锁Marshal.Copy(grayValues,0,ptr,scanBytes);bitmap.UnlockBits(bmpData);//解锁内存区域//returnbitmap;//修改生成位图的索引表ColorPalettepalette;//获取一个Format8bppIndexed格式图像的Palette对象using(Bitmapbmp=newBitmap(1,1,PixelFormat.Format1bppIndexed)){palette=bmp.Palette;}for(inti=0;i<2;i++){palette.Entries[i]=Color.FromArgb(i*255,i*255,i*255);}//修改生成位图的索引表bitmap.Palette=palette;returnbitmap;}
参数rawValues就是#4得到的灰度数据byColorInfo
解决方案十一:
代码是套改8位灰度图的,注释不准确,请原谅
解决方案十二:
另外,对微软的色彩转黑白的抖动算法不甚了解转出的图片和画图转的不太一样
解决方案十三:
引用9楼xuzuning的回复:
你要的是这个效果吧?把左边的24位真彩,转成右边的单色位图privatestaticBitmapBuiltBlackWhiteBitmap(byte[]rawValues,intwidth,intheight){//新建一个8位灰度位图,并锁定内存区域操作Bitmapbitmap=newBitmap(width,height,PixelFormat.Format1bppIndexed);BitmapDatabmpData=bitmap.LockBits(newRectangle(0,0,width,height),ImageLockMode.WriteOnly,PixelFormat.Format1bppIndexed);//计算图像参数intoffset=bmpData.Stride-bmpData.Width/8;//计算每行未用空间字节数IntPtrptr=bmpData.Scan0;//获取首地址intscanBytes=bmpData.Stride*bmpData.Height;//图像字节数=扫描字节数*高度byte[]grayValues=newbyte[scanBytes];//为图像数据分配内存//为图像数据赋值intposSrc=0,posScan=0;//rawValues和grayValues的索引for(inti=0;i<height;i++){for(intj=0;j<width/8;j++){byteb=0;for(intk=0;k<8;k++)b=(byte)((b<<1)|(byte)(rawValues[posSrc++]<96?0:1));grayValues[posScan++]=b;}//跳过图像数据每行未用空间的字节,length=stride-width*bytePerPixelposScan+=offset;}//内存解锁Marshal.Copy(grayValues,0,ptr,scanBytes);bitmap.UnlockBits(bmpData);//解锁内存区域//returnbitmap;//修改生成位图的索引表ColorPalettepalette;//获取一个Format8bppIndexed格式图像的Palette对象using(Bitmapbmp=newBitmap(1,1,PixelFormat.Format1bppIndexed)){palette=bmp.Palette;}for(inti=0;i<2;i++){palette.Entries[i]=Color.FromArgb(i*255,i*255,i*255);}//修改生成位图的索引表bitmap.Palette=palette;returnbitmap;}参数rawValues就是#4得到的灰度数据byColorInfo
不明白rawValues是使用灰度数据还是原始数据。
解决方案十四:
最简单的两句代码就能搞定要想要二值化自定义阈值就用上面的代码
解决方案十五:
引用13楼crystal_lz的回复:
最简单的两句代码就能搞定要想要二值化自定义阈值就用上面的代码
但是和图片用画图工具打开保存的单色位图不一样!
解决方案:
.net中有现成的转换方法,只要执行Image.Save即可。把24L改为1L,或者别的值。
解决方案:
我说的很清楚了:参数rawValues就是#4得到的灰度数据byColorInfo也说了产生的位图与画图的不一样你可自行调整21行处的代码
解决方案:
引用14楼u013416462的回复:
但是和图片用画图工具打开保存的单色位图不一样!
你看到的不是“单色”,是“灰度”吧?
解决方案:
单色就是Encoder.ColorDepth==1L,而灰度的图片那就是Encoder.ColorDepth==8L。