C#图像处理
C#Bitmap有没有可以处理图片的函数?我希望能够使图片显示出来的效果就跟加了一层薄纱一样不知道能否实现最好有代码...
C#Bitmap有没有可以处理图片的函数?我希望能够使图片显示出来的效果就跟加了一层薄纱一样 不知道能否实现 最好有代码
展开
1个回答
展开全部
由于C#托管代码中不能使用指针(后来经过我的验证,即使是在unsafe代码中用指针操作,速度仍然很慢),因此我们就不能像C++里面一样直接利用指针在内存中完成读写操作。好在.NET Framework提供了托管内存与非托管内存之间的读写功能,一个强大的Marshal类,使得我们快速读写图像的像素信息成为可能。
在.NET Framework 2.0中,Bitmap类多了两个有关内存操作的新方法:LockBits与UnlockBits,其具体含义请参见MSDN,我在这里就直接给出利用它们以及Marshal类进行内存读写的代码。上面的GetRGB方法经过改进之后:
public static bool GetRGB(Bitmap Source, out int[,] R, out int[,] G, out int[,] B)
{
try
{
int iWidth = Source.Width;
int iHeight = Source.Height;
Rectangle rect = new Rectangle(0, 0, iWidth, iHeight);
System.Drawing.Imaging.BitmapData bmpData = Source.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, Source.PixelFormat);
IntPtr iPtr = bmpData.Scan0;
int iBytes = iWidth * iHeight * 3;
byte[] PixelValues = new byte[iBytes];
System.Runtime.InteropServices.Marshal.Copy(iPtr, PixelValues, 0, iBytes);
Source.UnlockBits(bmpData);
// 注意这个地方图像的两维方向与数组两维的方向是转置的关系
R = new int[iHeight, iWidth];
G = new int[iHeight, iWidth];
B = new int[iHeight, iWidth];
int iPoint = 0;
for (int i = 0; i < iHeight; i++)
{
for (int j = 0; j < iWidth; j++)
{
// 注意,Windows 中三基色的排列顺序是 BGR 而不是 RGB!
B[i, j] = Convert.ToInt32(PixelValues[iPoint++]);
G[i, j] = Convert.ToInt32(PixelValues[iPoint++]);
R[i, j] = Convert.ToInt32(PixelValues[iPoint++]);
}
}
return true;
}
catch (Exception)
{
R = null;
G = null;
B = null;
return false;
}
}
提醒注意的是,这段代码仅仅适合于像素是24位RGB的图像(8位R、8位B和8位G,不包含Alpha通道,Format24bppRgb),如果要其它像素格式的(可以参见System.Drawing.Imaging.PixelFormat的成员),可以此类推,加上一组case语句,成为完整功能的读图方法。
回写则与之相反,把需要写入的像素信息先写到byte数组中,再调用Marshal.Copy的第一个重载方法即可。下面给出我从灰度矩阵构建Bitmap类的方法:
/// <summary>
/// 由灰度矩阵创建位图
/// </summary>
/// <param name="Gray">灰度矩阵(取值0~255)</param>
/// <returns>矩阵对应的位图</returns>
public static Bitmap FromGray(int[,] Gray)
{
int iWidth = Gray.GetLength(1);
int iHeight = Gray.GetLength(0);
Bitmap Result=new Bitmap(iWidth,iHeight,System.Drawing.Imaging.PixelFormat.Format24bppRgb);
Rectangle rect=new Rectangle(0,0,iWidth,iHeight);
System.Drawing.Imaging.BitmapData bmpData = Result.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
IntPtr iPtr = bmpData.Scan0;
int iStride = bmpData.Stride;
int iBytes = iWidth * iHeight * 3;
byte[] PixelValues = new byte[iBytes];
int iPoint=0;
for (int i=0;i<iHeight;i++)
for (int j = 0; j < iWidth; j++)
{
int iGray = Gray[i, j];
PixelValues[iPoint] = PixelValues[iPoint + 1] = PixelValues[iPoint + 2] = Convert.ToByte(iGray);
iPoint += 3;
}
System.Runtime.InteropServices.Marshal.Copy(PixelValues, 0, iPtr, iBytes);
Result.UnlockBits(bmpData);
return Result;
}
.NET Framework的博大精深,需要你我细心品味……
是否可以解决您的问题?
在.NET Framework 2.0中,Bitmap类多了两个有关内存操作的新方法:LockBits与UnlockBits,其具体含义请参见MSDN,我在这里就直接给出利用它们以及Marshal类进行内存读写的代码。上面的GetRGB方法经过改进之后:
public static bool GetRGB(Bitmap Source, out int[,] R, out int[,] G, out int[,] B)
{
try
{
int iWidth = Source.Width;
int iHeight = Source.Height;
Rectangle rect = new Rectangle(0, 0, iWidth, iHeight);
System.Drawing.Imaging.BitmapData bmpData = Source.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, Source.PixelFormat);
IntPtr iPtr = bmpData.Scan0;
int iBytes = iWidth * iHeight * 3;
byte[] PixelValues = new byte[iBytes];
System.Runtime.InteropServices.Marshal.Copy(iPtr, PixelValues, 0, iBytes);
Source.UnlockBits(bmpData);
// 注意这个地方图像的两维方向与数组两维的方向是转置的关系
R = new int[iHeight, iWidth];
G = new int[iHeight, iWidth];
B = new int[iHeight, iWidth];
int iPoint = 0;
for (int i = 0; i < iHeight; i++)
{
for (int j = 0; j < iWidth; j++)
{
// 注意,Windows 中三基色的排列顺序是 BGR 而不是 RGB!
B[i, j] = Convert.ToInt32(PixelValues[iPoint++]);
G[i, j] = Convert.ToInt32(PixelValues[iPoint++]);
R[i, j] = Convert.ToInt32(PixelValues[iPoint++]);
}
}
return true;
}
catch (Exception)
{
R = null;
G = null;
B = null;
return false;
}
}
提醒注意的是,这段代码仅仅适合于像素是24位RGB的图像(8位R、8位B和8位G,不包含Alpha通道,Format24bppRgb),如果要其它像素格式的(可以参见System.Drawing.Imaging.PixelFormat的成员),可以此类推,加上一组case语句,成为完整功能的读图方法。
回写则与之相反,把需要写入的像素信息先写到byte数组中,再调用Marshal.Copy的第一个重载方法即可。下面给出我从灰度矩阵构建Bitmap类的方法:
/// <summary>
/// 由灰度矩阵创建位图
/// </summary>
/// <param name="Gray">灰度矩阵(取值0~255)</param>
/// <returns>矩阵对应的位图</returns>
public static Bitmap FromGray(int[,] Gray)
{
int iWidth = Gray.GetLength(1);
int iHeight = Gray.GetLength(0);
Bitmap Result=new Bitmap(iWidth,iHeight,System.Drawing.Imaging.PixelFormat.Format24bppRgb);
Rectangle rect=new Rectangle(0,0,iWidth,iHeight);
System.Drawing.Imaging.BitmapData bmpData = Result.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
IntPtr iPtr = bmpData.Scan0;
int iStride = bmpData.Stride;
int iBytes = iWidth * iHeight * 3;
byte[] PixelValues = new byte[iBytes];
int iPoint=0;
for (int i=0;i<iHeight;i++)
for (int j = 0; j < iWidth; j++)
{
int iGray = Gray[i, j];
PixelValues[iPoint] = PixelValues[iPoint + 1] = PixelValues[iPoint + 2] = Convert.ToByte(iGray);
iPoint += 3;
}
System.Runtime.InteropServices.Marshal.Copy(PixelValues, 0, iPtr, iBytes);
Result.UnlockBits(bmpData);
return Result;
}
.NET Framework的博大精深,需要你我细心品味……
是否可以解决您的问题?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询