C#图片处理之:最简单的柔化算法
2012-01-17 13:52
281 查看
与锐化相反,柔化是使图片看起来更柔滑(其实也是模糊的委婉的说法)。柔化的一个最简单的实现算法就是取图片上的每一点(图片边缘点忽略),计算它周围八个点的平均值作为新像素值。想想也是,之所以看起来模糊,确实是因为周围的点长的有点像,区别不太明显。
// ============================柔化==============================
/**//// <summary>
/// 柔化
/// <param name="b">原始图</param>
/// <returns>输出图</returns>
public static Bitmap KiBlur(Bitmap b)
...{
if (b == null)
...{
return null;
}
int w = b.Width;
int h = b.Height;
try
...{
Bitmap bmpRtn = new Bitmap(w, h, PixelFormat.Format24bppRgb);
BitmapData srcData = b.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
BitmapData dstData = bmpRtn.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
unsafe
...{
byte* pIn = (byte*)srcData.Scan0.ToPointer();
byte* pOut = (byte*)dstData.Scan0.ToPointer();
int stride = srcData.Stride;
byte* p;
for (int y = 0; y < h; y++)
...{
for (int x = 0; x < w; x++)
...{
//取周围9点的值
if (x == 0 || x == w - 1 || y == 0 || y == h - 1)
...{
//不做
pOut[0] = pIn[0];
pOut[1] = pIn[1];
pOut[2] = pIn[2];
}
else
...{
int r1, r2, r3, r4, r5, r6, r7, r8, r9;
int g1, g2, g3, g4, g5, g6, g7, g8, g9;
int b1, b2, b3, b4, b5, b6, b7, b8, b9;
float vR, vG, vB;
//左上
p = pIn - stride - 3;
r1 = p[2];
g1 = p[1];
b1 = p[0];
//正上
p = pIn - stride;
r2 = p[2];
g2 = p[1];
b2 = p[0];
//右上
p = pIn - stride + 3;
r3 = p[2];
g3 = p[1];
b3 = p[0];
//左侧
p = pIn - 3;
r4 = p[2];
g4 = p[1];
b4 = p[0];
//右侧
p = pIn + 3;
r5 = p[2];
g5 = p[1];
b5 = p[0];
//右下
p = pIn + stride - 3;
r6 = p[2];
g6 = p[1];
b6 = p[0];
//正下
p = pIn + stride;
r7 = p[2];
g7 = p[1];
b7 = p[0];
//右下
p = pIn + stride + 3;
r8 = p[2];
g8 = p[1];
b8 = p[0];
//自己
p = pIn;
r9 = p[2];
g9 = p[1];
b9 = p[0];
vR = (float)(r1 + r2 + r3 + r4 + r5 + r6 + r7 + r8 + r9);
vG = (float)(g1 + g2 + g3 + g4 + g5 + g6 + g7 + g8 + g9);
vB = (float)(b1 + b2 + b3 + b4 + b5 + b6 + b7 + b8 + b9);
vR /= 9;
vG /= 9;
vB /= 9;
pOut[0] = (byte)vB;
pOut[1] = (byte)vG;
pOut[2] = (byte)vR;
}
pIn += 3;
pOut += 3;
}// end of x
pIn += srcData.Stride - w * 3;
pOut += srcData.Stride - w * 3;
} // end of y
}
b.UnlockBits(srcData);
bmpRtn.UnlockBits(dstData);
return bmpRtn;
}
catch
...{
return null;
}
} // end of KiBlur
当然这是最简单的一种,不支持柔化半径选择。实际中通常需要自定义模糊的程度,这个下回再谈。
// ============================柔化==============================
/**//// <summary>
/// 柔化
/// <param name="b">原始图</param>
/// <returns>输出图</returns>
public static Bitmap KiBlur(Bitmap b)
...{
if (b == null)
...{
return null;
}
int w = b.Width;
int h = b.Height;
try
...{
Bitmap bmpRtn = new Bitmap(w, h, PixelFormat.Format24bppRgb);
BitmapData srcData = b.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
BitmapData dstData = bmpRtn.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
unsafe
...{
byte* pIn = (byte*)srcData.Scan0.ToPointer();
byte* pOut = (byte*)dstData.Scan0.ToPointer();
int stride = srcData.Stride;
byte* p;
for (int y = 0; y < h; y++)
...{
for (int x = 0; x < w; x++)
...{
//取周围9点的值
if (x == 0 || x == w - 1 || y == 0 || y == h - 1)
...{
//不做
pOut[0] = pIn[0];
pOut[1] = pIn[1];
pOut[2] = pIn[2];
}
else
...{
int r1, r2, r3, r4, r5, r6, r7, r8, r9;
int g1, g2, g3, g4, g5, g6, g7, g8, g9;
int b1, b2, b3, b4, b5, b6, b7, b8, b9;
float vR, vG, vB;
//左上
p = pIn - stride - 3;
r1 = p[2];
g1 = p[1];
b1 = p[0];
//正上
p = pIn - stride;
r2 = p[2];
g2 = p[1];
b2 = p[0];
//右上
p = pIn - stride + 3;
r3 = p[2];
g3 = p[1];
b3 = p[0];
//左侧
p = pIn - 3;
r4 = p[2];
g4 = p[1];
b4 = p[0];
//右侧
p = pIn + 3;
r5 = p[2];
g5 = p[1];
b5 = p[0];
//右下
p = pIn + stride - 3;
r6 = p[2];
g6 = p[1];
b6 = p[0];
//正下
p = pIn + stride;
r7 = p[2];
g7 = p[1];
b7 = p[0];
//右下
p = pIn + stride + 3;
r8 = p[2];
g8 = p[1];
b8 = p[0];
//自己
p = pIn;
r9 = p[2];
g9 = p[1];
b9 = p[0];
vR = (float)(r1 + r2 + r3 + r4 + r5 + r6 + r7 + r8 + r9);
vG = (float)(g1 + g2 + g3 + g4 + g5 + g6 + g7 + g8 + g9);
vB = (float)(b1 + b2 + b3 + b4 + b5 + b6 + b7 + b8 + b9);
vR /= 9;
vG /= 9;
vB /= 9;
pOut[0] = (byte)vB;
pOut[1] = (byte)vG;
pOut[2] = (byte)vR;
}
pIn += 3;
pOut += 3;
}// end of x
pIn += srcData.Stride - w * 3;
pOut += srcData.Stride - w * 3;
} // end of y
}
b.UnlockBits(srcData);
bmpRtn.UnlockBits(dstData);
return bmpRtn;
}
catch
...{
return null;
}
} // end of KiBlur
当然这是最简单的一种,不支持柔化半径选择。实际中通常需要自定义模糊的程度,这个下回再谈。
相关文章推荐
- 简单的GDI+处理图片大小(C#代码)
- C#的简单图片透明处理
- C#的简单图片透明处理
- C#对图片的几种简单处理
- C#图像处理(各种旋转、改变大小、柔化、锐化、雾化、底片、浮雕、黑白、滤镜效果,滤波,图像截取) 对图片的处理 : 亮度调整 抓屏 翻转 随鼠标画矩形
- 【C#】图片处理(底片,黑白,锐化,柔化,浮雕,雾化)
- 简单的GDI+处理图片大小(C#代码)
- C#对图片的几种简单处理 [ZT]
- C#图片处理之:最简单的柔化算法
- C#对图片的几种简单处理
- 计算机视觉一些简单图片处理算法
- 【C#】图片处理(底片,黑白,锐化,柔化,浮雕,雾化)
- C#开发——简单的图片处理方法(更新中)
- C#对图片的几种简单处理
- C#对图片的几种简单处理
- 用最简单的方式在C#中使用多线程加速耗时的图像处理算法的执行(多核机器)。
- 用最简单的方式在C#中使用多线程加速耗时的图像处理算法的执行(多核机器)。
- C#对图片的几种简单处理
- 图像处理之基础---肤色检测算法 - 基于不同颜色空间简单区域划分的皮肤检测算法
- C# 后台处理图片的几种方式