C#处理数码相片之马赛克的实现

2008-02-23 05:39:45来源:互联网 阅读 ()

新老客户大回馈,云服务器低至5折

  很多图片处理的算法从原理上讲其实很简单,难点往往在如何去写算法实现他,更加难的就是如何去优化实现的算法。虽说我一向认为程式员的效率比程式的效率更重要,但为了等处理一张自己拍摄的数码照片,溜出去买杯奶茶顺便再买张彩票回来发现还没算好,无论如何都是不能忍受的。

  马赛克算法很简单,说白了就是把一张图片分割成若干个val * val像素的小区块(可能在边缘有零星的小块,但不影响整体算法),每个小区块的颜色都是相同的。为了方便起见,我们不妨让这个颜色就用该区域最左上角的那个点的颜色。当然还能够有其他方法,比如取区块中间点的颜色,或区块中随机点的颜色作代表等等。

  下面的示意图就是取val=2的结果。

  原图像素
  ABCDEFG
  HIJKLMN
  OPQRSTU
  VWXYZ01
  2345678

  马赛克处理后
  AACCEEG
  AACCEEG
  OOQQSSU
  OOQQSSU
  2244668

  原理就是那么简单。具体实现就看各人的思维习惯了。我的想法是:

  当y(当前高度)是val的整数倍时:
  扫描当前行中的每一点x,假如x也是val的整数倍,记录下当前x,y的颜色值;假如x不是val的整数倍,则沿用最近一次被记录的颜色值。
当y不是val的整数倍:
很简单,直接复制上一行。

  简单的说就是以线带面,最终实现让大家都看不清楚

  下面就是源代码。写算法不是我的强项,但是偶尔勉为其难的写个能够跑跑的不求甚解版还是能够做到的,不指望能够帮到您,只希望没有误导您。

public static Bitmap KiMosaic(Bitmap b, int val)
{
if (b.Equals(null))
{
return null;
}

int w = b.Width;
int h = b.Height;

int stdR, stdG, stdB;

stdR = 0;
stdG = 0;
stdB = 0;

BitmapData srcData = b.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

unsafe
{
byte* p = (byte*)srcData.Scan0.ToPointer();

for (int y = 0; y < h; y )
{
for (int x = 0; x < w; x )
{
if (y % val == 0)
{
if (x % val == 0)
{
stdR = p[2]; stdG = p[1]; stdB = p[0];
}
else
{
p[0] = (byte)stdB;
p[1] = (byte)stdG;
p[2] = (byte)stdR;
}
}
else
{
// 复制上一行
byte * pTemp = p - srcData.Stride;

p[0] = (byte)pTemp[0];
p[1] = (byte)pTemp[1];
p[2] = (byte)pTemp[2];
}

p = 3;

} // end of x

p = srcData.Stride - w * 3;

} // end of y

b.UnlockBits(srcData);
}

return b;

}




标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇: C 语言最大难点揭秘[2]

下一篇: .Net环境下基于Ajax的MVC方案[2]

热门词条
热门标签