實現(xiàn)C#馬賽克算法
應聽眾點播要求,今天講講C#馬賽克算法的實現(xiàn)。老規(guī)矩,不求甚解,只許看不許問為什么
很多圖片處理的算法從原理上講其實非常簡單,難點往往在如何去寫算法實現(xiàn)它,更加難的就是如何去優(yōu)化實現(xiàn)的算法。雖說我一向認為程序員的效率比程序的效率更重要,但為了等處理一張自己拍攝的數(shù)碼照片,溜出去買杯奶茶順便再買張彩票回來發(fā)現(xiàn)還沒算好,無論如何都是不能忍受的。
C#馬賽克算法很簡單,說白了就是把一張圖片分割成若干個val * val像素的小區(qū)塊(可能在邊緣有零星的小塊,但不影響整體算法),每個小區(qū)塊的顏色都是相同的。為了方便起見,我們不妨讓這個顏色就用該區(qū)域最左上角的那個點的顏色。當然還可以有其他方法,比如取區(qū)塊中間點的顏色,或區(qū)塊中隨機點的顏色作代表等等。
下面的示意圖就是取val=2的結(jié)果。
原圖像素
ABCDEFG
HIJKLMN
OPQRSTU
VWXYZ01
2345678
馬賽克處理后
AACCEEG
AACCEEG
OOQQSSU
OOQQSSU
2244668
原理就是那么簡單。具體實現(xiàn)就看各人的思維習慣了。我的想法是:
當y(當前高度)是val的整數(shù)倍時:
掃描當前行中的每一點x,如果x也是val的整數(shù)倍,記錄下當前x,y的顏色值;如果x不是val的整數(shù)倍,則沿用最近一次被記錄的顏色值。
當y不是val的整數(shù)倍:
很簡單,直接復制上一行。
簡單的說就是以線帶面,最終實現(xiàn)讓大家都看不清楚
下面就是源代碼。寫算法不是我的強項,不過偶爾勉為其難的寫個可以跑跑的不求甚解版還是可以做到的,不指望可以幫到你,只希望沒有誤導你。
- publicstaticBitmapKiMosaic(Bitmapb,intval)
- {
- if(b.Equals(null))
- {
- returnnull;
- }
- intw=b.Width;
- inth=b.Height;
- intstdR,stdG,stdB;
- stdR=0;
- stdG=0;
- stdB=0;
- BitmapDatasrcData=b.LockBits(newRectangle(0,0,w,h),
ImageLockMode.ReadWrite,PixelFormat.Format24bppRgb);- unsafe
- {
- byte*p=(byte*)srcData.Scan0.ToPointer();
- for(inty=0;y<h;y++)
- {
- for(intx=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*ppTemp=p-srcData.Stride;
- p[0]=(byte)pTemp[0];
- p[1]=(byte)pTemp[1];
- p[2]=(byte)pTemp[2];
- }
- p+=3;
- }//endofx
- p+=srcData.Stride-w*3;
- }//endofy
- b.UnlockBits(srcData);
- }
- returnb;
- }
以上介紹C#馬賽克算法
【編輯推薦】