当前位置:编程学习 > C#/ASP.NET >>

winfrom 将bmp转换为bmp格式的单色图

引用楼主 gemeihao 的回复:
▪ 中小企业如何利用云计算构建网...▪ 厂商为什么各自都推出了不同的...▪ 云计算与大数据领域的关系是?▪ CIO选择云计算带来的时间节省是...▪ 如何利用云计算节约能源?
winfrom 将bmp转换为bmp格式的单色图
位深度为1



以上代码是一个高手提高的  但是有时候可以实现  但是有时候又不行   转换后的图片内容是空的   但是转换前的内容是正常的      希望高手支招 --------------------编程问答-------------------- 以下就是高手的代码  但是有时候可以实现 但是有时候又不行 转换后的图片内容是空的 但是转换前的内容是正常的 希望高手支招



转贴代码,参考一下:
C# codeusing System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;

//打开任一索引色的或者非索引色的图像
Image img=Image.FromFile("r.bmp");
ImageAttributes ta=new ImageAttributes();
/* 下面用Graphics类改变像点颜色,是靠ImageAttributes来把
* 彩色变成灰度,或者颠倒黑白,发现用矩阵处理还是很方便的
*/
//如实际发现几个简单又好用的矩阵:
/* float[][] mm=new float[][]{ //彩色变灰度的矩阵
  new float[]{0.4f, 0.4f, 0.4f, 0, 0},
  new float[]{0.3f, 0.3f, 0.3f, 0, 0},
  new float[]{0.3f, 0.3f, 0.3f, 0, 0},
  new float[]{0, 0, 0, 1, 0},
  new float[]{0, 0, 0, 0, 1}
};
float[][] mm1=new float[][]{ //彩色反相的矩阵
  new float[]{0, 0.3f, 0.5f, 0, 0},
  new float[]{0.5f, 0.3f, 0.5f, 0, 0},
  new float[]{0.5f, 0.4f, 0, 0, 0},
  new float[]{0, 0, 0, 1, 0},
  new float[]{0, 0, 0, 0, 1}
};
*/
float[][] mm2=new float[][]{ //彩色变反相灰度的矩阵
  new float[]{-0.4f, -0.4f, -0.4f, 0, 0},
  new float[]{-0.3f, -0.3f, -0.3f, 0, 0},
  new float[]{-0.3f, -0.3f, -0.3f, 0, 0},
  new float[]{1, 1, 1, 1, 0},
  new float[]{0, 0, 0, 0, 1}
};
ColorMatrix cmt=new ColorMatrix(mm2);
ta.SetColorMatrix(cmt);
/* //如果确知图像里仅有纯黑白二色,也可用ColorMap来反相,它可逐色改变
ColorMap map1=new ColorMap();
map1.OldColor=Color.Black;
map1.NewColor=Color.White;
ColorMap map2=new ColorMap();
map2.OldColor=Color.White;
map2.NewColor=Color.Black;
ta.SetRemapTable(new ColorMap[]{map1,map2},ColorAdjustType.Bitmap);
*/
/* 有的图像比如索引格式的位图或GIF是无法创建Graphics的,
* 需要新建一非索引色位图取得Graphics对象以便做画或改变像点颜色。
*/
Bitmap bmp=new Bitmap(img.Width,img.Height);
Graphics g=Graphics.FromImage(bmp);
g.DrawImage(img,new Rectangle(0,0,bmp.Width,bmp.Height),0,0,img.Width,img.Height,GraphicsUnit.Pixel,ta);
//g.DrawString("Foxit PDF Reader",new Font("宋体",8),new SolidBrush(Color.White),0,0);
g.Dispose();
/* 在如下构造图像数据之前,也可以先创建一单色位图并锁定数据,
* 利用它现成的Stride简单计算出实际每行有效数据之后的填充字节数,而且可
* 在下面循环里直接写点Marshal.WriteByte(dt.Scan0,k,val);而不用数组拷贝
*/
//以下,把反相或者涂画后的像点数据每一行的每8点简单合并成1byte存储
int midrgb=Color.FromArgb(128,128,128).ToArgb();
int stride;//简单公式((width/8)+3)&(~3)
stride = (bmp.Width%8)==0 ? (bmp.Width/8) : (bmp.Width/8)+1;
stride = (stride%4)==0 ? stride : ((stride/4)+1)*4;
int k=bmp.Height*stride;
byte[] buf=new byte[k];
for(int j=0;j<bmp.Height;j++){
  k=j*stride;//因图像宽度不同、有的可能有填充字节需要跳越
  int x=0,ab=0;
  for(int i=0;i<bmp.Width;i++){
  //从灰度变单色(下法如果直接从彩色变单色效果不太好,不过反相也可以在这里控制)
  if ((bmp.GetPixel(i,j)).ToArgb() > midrgb) ab=ab*2+1; else ab=ab*2;
  x++;
  if(x==8){
  buf[k++]=(byte)ab;
  ab=0;
  x=0;
  }
  }
  if(x>0){
  //循环实现:剩余有效数据不满1字节的情况下须把它们移往字节的高位部分
  for(int t=x;t<8;t++)ab=ab*2;
  buf[k++]=(byte)ab;
  }
}
Bitmap bb=new Bitmap(img.Width,img.Height,PixelFormat.Format1bppIndexed);
BitmapData dt=bb.LockBits(new Rectangle(0,0,bb.Width,bb.Height),ImageLockMode.ReadWrite,bb.PixelFormat);
Marshal.Copy(buf,0,dt.Scan0,buf.Length);
bb.UnlockBits(dt);
bb.Save("w.bmp",ImageFormat.Bmp);
bb.Dispose();
bmp.Dispose();
img.Dispose();

补充:.NET技术 ,  .NET Framework
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,