您的位置:首页 > 编程语言 > C#

c#转为8位灰度图像和转为1位黑白图像

2014-11-11 09:10 597 查看
#region 位深度为1的黑白图

/// <summary>

/// 转为黑白图

/// </summary>

/// <param name="SrcImg"></param>

/// <returns></returns>

public static Bitmap ConvertTo24bppTo1bpp(Bitmap SrcImg, byte Threshoding)

{

unsafe

{

byte* SrcPointer, DestPointer;

int Width, Height, SrcStride, DestStride;

int X, Y, Index, Sum; ;

Bitmap DestImg = new Bitmap(SrcImg.Width, SrcImg.Height, PixelFormat.Format1bppIndexed);

BitmapData SrcData = new BitmapData();

SrcImg.LockBits(new Rectangle(0, 0, SrcImg.Width, SrcImg.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb, SrcData);

BitmapData DestData = new BitmapData();

DestImg.LockBits(new Rectangle(0, 0, SrcImg.Width, SrcImg.Height), ImageLockMode.ReadWrite, PixelFormat.Format1bppIndexed, DestData);

Width = SrcImg.Width; Height = SrcImg.Height; SrcStride = SrcData.Stride; DestStride = DestData.Stride;

for (Y = 0; Y < Height; Y++)

{

SrcPointer = (byte*)SrcData.Scan0 + Y * SrcStride;

DestPointer = (byte*)DestData.Scan0 + Y * DestStride;

Index = 7; Sum = 0;

for (X = 0; X < Width; X++)

{

if (*SrcPointer + (*(SrcPointer + 1) << 1) + *(SrcPointer + 2) >> 2 >= Threshoding)

{

Sum += (1 << Index);

}

if (Index == 0)

{

*DestPointer = (byte)Sum;

Sum = 0;

Index = 7;

DestPointer++;

}

else

Index--;

SrcPointer += 3;

}

if (Index != 7)

*DestPointer = (byte)Sum;

}

SrcImg.UnlockBits(SrcData);

DestImg.UnlockBits(DestData);

return DestImg;

}

}

#endregion

#region 转为位深度为8的灰度图像

/// <summary>

/// 转为灰度图像,位深度也改变

/// </summary>

/// <param name="srcBitmap"></param>

/// <returns></returns>

public static Bitmap RGB2Gray(Bitmap srcBitmap)

{

int wide = srcBitmap.Width;

int height = srcBitmap.Height;

Rectangle rect = new Rectangle(0, 0, wide, height);

//将Bitmap锁定到系统内存中,获得BitmapData

BitmapData srcBmData = srcBitmap.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

//创建Bitmap

Bitmap dstBitmap = CreateGrayscaleImage(wide, height);//这个函数在后面有定义

BitmapData dstBmData = dstBitmap.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);

//位图中第一个像素数据的地址。它也可以看成是位图中的第一个扫描行

System.IntPtr srcPtr = srcBmData.Scan0;

System.IntPtr dstPtr = dstBmData.Scan0;

//将Bitmap对象的信息存放到byte数组中

int src_bytes = srcBmData.Stride * height;

byte[] srcValues = new byte[src_bytes];

int dst_bytes = dstBmData.Stride * height;

byte[] dstValues = new byte[dst_bytes];

//复制GRB信息到byte数组

System.Runtime.InteropServices.Marshal.Copy(srcPtr, srcValues, 0, src_bytes);

System.Runtime.InteropServices.Marshal.Copy(dstPtr, dstValues, 0, dst_bytes);

//根据Y=0.299*R+0.114*G+0.587B,Y为亮度

for (int i = 0; i < height; i++)

for (int j = 0; j < wide; j++)

{

//只处理每行中图像像素数据,舍弃未用空间

//注意位图结构中RGB按BGR的顺序存储

int k = 3 * j;

byte temp = (byte)(srcValues[i * srcBmData.Stride + k + 2] * .299 + srcValues[i * srcBmData.Stride + k + 1] * .587 + srcValues[i * srcBmData.Stride + k] * .114);

dstValues[i * dstBmData.Stride + j] = temp;

}

System.Runtime.InteropServices.Marshal.Copy(dstValues, 0, dstPtr, dst_bytes);

//解锁位图

srcBitmap.UnlockBits(srcBmData);

dstBitmap.UnlockBits(dstBmData);

return dstBitmap;

}

/// <summary>

/// 创建8位灰度图像

/// </summary>

/// <param name="width"></param>

/// <param name="height"></param>

/// <returns></returns>

public static Bitmap CreateGrayscaleImage(int width, int height)

{

// create new image

Bitmap bmp = new Bitmap(width, height, PixelFormat.Format8bppIndexed);

// set palette to grayscale

SetGrayscalePalette(bmp);

// return new image

return bmp;

}

///<summary>

/// Set pallete of the image to grayscale

///</summary>

public static void SetGrayscalePalette(Bitmap srcImg)

{

// check pixel format

if (srcImg.PixelFormat != PixelFormat.Format8bppIndexed)

throw new ArgumentException();

// get palette

ColorPalette cp = srcImg.Palette;

// init palette

for (int i = 0; i < 256; i++)

{

cp.Entries[i] = Color.FromArgb(i, i, i);

}

srcImg.Palette = cp;

}

#endregion
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐