一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

Android圖片處理(Matrix,ColorMatrix)

 JUST SO LAZY 2015-03-03

在編程中有時候需要對圖片做特殊的處理,比如將圖片做出黑白的,或者老照片的效果,有時候還要對圖片進行變換,以拉伸,扭曲等等。


這些效果在android中有很好的支持,通過顏色矩陣(ColorMatrix)和坐標變換矩陣(Matrix)可以完美的做出上面的所說的效果。


下面將分別介紹這兩個矩陣的用法和相關(guān)的函數(shù)。


顏色矩陣
android中可以通過顏色矩陣(ColorMatrix類)方面的操作顏色,顏色矩陣是一個5x4 的矩陣(如圖1.1)


可以用來方面的修改圖片中RGBA各分量的值,顏色矩陣以一維數(shù)組的方式存儲如下:
 [ a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t ]
他通過RGBA四個通道來直接操作對應(yīng)顏色,如果會使用Photoshop就會知道有時處理圖片通過控制RGBA各顏色通道來做出特殊的效果。


這個矩陣對顏色的作用計算方式如1.3示:


矩陣的運算規(guī)則是矩陣A的一行乘以矩陣C的一列作為矩陣R的一行,


C矩陣是圖片中包含的ARGB信息,R矩陣是用顏色矩陣應(yīng)用于C之后的新的顏色分量,運算結(jié)果如下:
 
R' = a*R + b*G + c*B + d*A + e;
G' = f*R + g*G + h*B + i*A + j;
B' = k*R + l*G + m*B + n*A + o;
A' = p*R + q*G + r*B + s*A + t;
 
顏色矩陣并不是看上去那么深奧,其實需要使用的參數(shù)很少,而且很有規(guī)律第一行決定紅色第二行決定綠色


第三行決定藍色,第四行決定了透明度,第五列是顏色的偏移量。下面是一個實際中使用的顏色矩陣。


如果把這個矩陣作用于各顏色分量的話,R=A*C,計算后會發(fā)現(xiàn),各個顏色分量實際上沒有任何的改變(R'=R G'=G B'=B A'=A)。

圖1.5所示矩陣計算后會發(fā)現(xiàn)紅色分量增加100,綠色分量增加100,


這樣的效果就是圖片偏黃,因為紅色和綠色混合后得到黃色,黃色增加了100,圖片當然就偏黃了。

改變各顏色分量不僅可以通過修改第5列的顏色偏移量也可如上面矩陣所示將對應(yīng)的顏色值乘以一個倍數(shù),直接放大。


上圖1.6是將綠色分量乘以2變?yōu)樵瓉淼?倍。相信讀者至此已經(jīng)明白了如何通過顏色矩陣來改變各顏色分量。


下面編寫一段代碼來,通過調(diào)整顏色矩陣來獲得不同的顏色效果,JavaCode如下:
復(fù)制到剪貼板  Java代碼


復(fù)制代碼

1 CMatrix類: 
2  public class CMatrix extends Activity { 
3      
4     private Button change; 
5     private EditText [] et=new EditText[20]; 
6     private float []carray=new float[20]; 
7     private MyImage sv; 
8     @Override 
9     public void onCreate(Bundle savedInstanceState) { 
10         super.onCreate(savedInstanceState); 
11         setContentView(R.layout.main); 
12          
13        change=(Button)findViewById(R.id.set); 
14        sv=(MyImage)findViewById(R.id.MyImage); 
15      
16        for(int i=0;i<20;i++){ 
17            
18        et[i]=(EditText)findViewById(R.id.indexa+i); 
19        carray[i]=Float.valueOf(et[i].getText().toString()); 
20        } 
21          
22        change.setOnClickListener(l); 
23     } 
24      
25     private Button.OnClickListener l=new Button.OnClickListener(){ 
26   
27        @Override 
28        public void onClick(View arg0) { 
29            // TODO Auto-generated method stub 
30             getValues(); 
31            sv.setValues(carray); 
32            sv.invalidate(); 
33        } 
34          
35     }; 
36     public   void getValues(){ 
37         for(int i=0;i<20;i++){ 
38              
39             carray[i]=Float.valueOf(et[i].getText().toString()); 
40         } 
41          
42     } 
43   
44      
45
46 MyImage類繼承自View類: 
47 public class MyImage extends View { 
48     private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 
49     private Bitmap mBitmap; 
50     private float [] array=new float[20]; 
51      
52     private float mAngle; 
53      
54     public MyImage(Context context,AttributeSet attrs) { 
55         super(context,attrs); 
56          
57         mBitmap    = BitmapFactory.decodeResource(context.getResources(), 
58                                                R.drawable.test); 
59         invalidate(); 
60     } 
61     
62      
63     public void setValues(float [] a){ 
64         for(int i=0;i<20;i++){ 
65            array[i]=a[i]; 
66         } 
67          
68     } 
69      
70     @Override protected void onDraw(Canvas canvas) { 
71         Paint paint = mPaint; 
72          
73          
74          
75         paint.setColorFilter(null); 
76         canvas.drawBitmap(mBitmap, 0, 0, paint); 
77          
78         ColorMatrix cm = new ColorMatrix(); 
79        //設(shè)置顏色矩陣 
80        cm.set(array); 
81 //顏色濾鏡,將顏色矩陣應(yīng)用于圖片 
82         paint.setColorFilter(new ColorMatrixColorFilter(cm)); 
83 //繪圖 
84         canvas.drawBitmap(mBitmap, 0, 0, paint); 
85         Log.i("CMatrix", "--------->onDraw"); 
86   
87         
88     } 
89     
90





復(fù)制代碼

CMatrix類主要負責接收顏色矩陣的設(shè)置和重繪,沒有要說的。MyImage類中進行繪圖工作,首先設(shè)置顏色矩陣cm.set(..)從一維數(shù)組中讀取數(shù)據(jù)20個數(shù)據(jù)給顏色矩陣賦值,paint.setColorFilter(..)設(shè)置顏色濾鏡,然后繪圖,效果就出來了(這個過程和PS差不多)如下:





看到這里,相信大家對顏色矩陣的作用已經(jīng)有了一個直觀的感受,現(xiàn)在也可以嘗試做一個照片特效的軟件。


但是各種效果并不能讓用戶手動調(diào)節(jié)顏色矩陣,這里需要計算公式,由于本人并不是做圖形軟件的也不能提供,可以參考這個鏈接:
http://www.adobe.com/devnet/flash/articles/matrix_transformations/ColorMatrixDemo.swf



坐標變換矩陣
坐標變換矩陣是一個3*3的矩陣如圖2.1,用來對圖形進行坐標變化,將原來的坐標點轉(zhuǎn)移到新的坐標點,


因為一個圖片是有點陣和每一點上的顏色信息組成的,所以對坐標的變換,就是對每一點進行搬移形成新的圖片。


具體的說圖形的放大縮小,移動,旋轉(zhuǎn),透視,扭曲這些效果都可以用此矩陣來完成。


這個矩陣的作用是對坐標x,y進行變換計算結(jié)果如下:
x'=a*x+b*y+c
y'=d*x+e*y+f
通常情況下g=h=0,這樣使1=0*x+0*y+1恒成立。和顏色矩陣一樣,坐標變換矩陣真正使用的參數(shù)很少也很有規(guī)律。


上圖就是一個坐標變換矩陣的簡單例子,計算后發(fā)現(xiàn)x'=x+50,y'=y+50.


可見圖片的每一點都在x和y方向上平移到了(50,50)點處,這種效果就是平移效果,將圖片轉(zhuǎn)移到了(50,50)處。

計算上面得矩陣x'=2*x,y‘=2*y.經(jīng)過顏色矩陣和上面轉(zhuǎn)移效果學習,相信讀者可以明白這個矩陣的作用了,這個矩陣對圖片進行了放大,具體的說是放大了二倍。
下面將介紹幾種常用的變換矩陣:
1.      旋轉(zhuǎn)



繞原點逆時針旋轉(zhuǎn)θ度角的變換公式是 x' = xcosθ ? ysinθ 與 y。' = xsinθ +    ycosθ
2.      縮放



變換后長寬分別放大x'=scale*x;y'=scale*y.
3.         切變



4.         反射

( , )單位向量
5.         正投影

( , )單位向量
 
上面的各種效果也可以疊加在一起,既矩陣的組合變換,可以用矩陣乘法實現(xiàn)之,如:R=B(A*C)=(B*A)C,注意一點就是B*A和A*B一般是不等的。


下面將編一個小程序,通過控制坐標變換矩陣來達到控制圖形的目的,JavaCode如下:

復(fù)制到剪貼板  Java代碼



1


復(fù)制代碼

CooMatrix類: 
2  
3public class CooMatrix extends Activity { 
4     
5    private Button change; 
6    private EditText [] et=new EditText[9]; 
7    private float []carray=new float[9]; 
8    private MyImage sv; 
9    /** Called when the activity is first created. */ 
10    @Override 
11    public void onCreate(Bundle savedInstanceState) { 
12        super.onCreate(savedInstanceState); 
13        setContentView(R.layout.main); 
14         
15       change=(Button)findViewById(R.id.set); 
16       sv=(MyImage)findViewById(R.id.MyImage); 
17       
18       for(int i=0;i<9;i++){ 
19           
20       et[i]=(EditText)findViewById(R.id.indexa+i); 
21       carray[i]=Float.valueOf(et[i].getText().toString()); 
22        
23       } 
24         
25      change.setOnClickListener(l); 
26         
27       
28    } 
29     
30    private Button.OnClickListener l=new Button.OnClickListener(){ 
31  
32       @Override 
33       public void onClick(View arg0) { 
34           // TODO Auto-generated method stub 
35           getValues(); 
36           sv.setValues(carray); 
37           sv.invalidate(); 
38       } 
39         
40    }; 
41    public   void getValues(){ 
42        for(int i=0;i<9;i++){ 
43             
44            carray[i]=Float.valueOf(et[i].getText().toString()); 
45        } 
46         
47    } 
48  
49     
50
51MyImage類繼承自View類: 
52public class MyImage extends View { 
53    private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 
54    private Bitmap mBitmap; 
55    private float [] array=new float[9]; 
56     
57     
58     
59    public MyImage(Context context,AttributeSet attrs) { 
60        super(context,attrs); 
61         
62        mBitmap = BitmapFactory.decodeResource(context.getResources(), 
63                                               R.drawable.ic_launcher_android); 
64        invalidate(); 
65    } 
66    
67     
68    public void setValues(float [] a){ 
69        for(int i=0;i<9;i++){ 
70           array[i]=a[i]; 
71        } 
72         
73    } 
74     
75    @Override protected void onDraw(Canvas canvas) { 
76        Paint paint = mPaint; 
77        canvas.drawBitmap(mBitmap, 0, 0, paint); 
78        //new 一個坐標變換矩陣 
79        Matrix cm = new Matrix(); 
80//為坐標變換矩陣設(shè)置響應(yīng)的值 
81       cm.setValues(array); 
82//按照坐標變換矩陣的描述繪圖 
83        canvas.drawBitmap(mBitmap, cm, paint); 
84        Log.i("CMatrix", "--------->onDraw"); 
85  
86        
87    } 
88    
89

復(fù)制代碼






上面的代碼中類CooMatrix用于接收用戶輸入的坐標變換矩陣參數(shù),類MyImage接收參數(shù),通過setValues()設(shè)置矩陣參數(shù),然后Canvas調(diào)用drawBitmap繪圖。效果如下:






上面給出了用坐標變換矩陣做出的各種效果,用坐標變換矩陣可以方面的調(diào)節(jié)圖形的各種效果,


但是我們看看Matrix類就可以發(fā)現(xiàn),實際上,matrix類本身已經(jīng)提供了許多類似的方法,我們只要調(diào)用,就可以了。
 
setScale(float sx, float sy, float px, float py) 放大 
setSkew(float kx, float ky, float px, float py) 斜切 
setTranslate(float dx, float dy)                       平移 
setRotate(float degrees, float px, float py)    旋轉(zhuǎn) 
 
上面的函數(shù)提供了基本的變換平移,放大,旋轉(zhuǎn),斜切。為了做出更復(fù)雜的變換,同時不必親手去改動坐標變換矩陣,


Matrix類提供了許多Map方法,將原圖形映射到目標點構(gòu)成新的圖形,


下面簡述setPolyToPoly(float[] src, int srcIndex, float[] dst, int dstIndex, int pointCount) 的用法,希望起到舉一反三的作用。


參數(shù)src和dst是分別存儲了原圖像的點和和指定的目標點的一維數(shù)組,數(shù)組中存儲的坐標格式如下:
 [x0, y0, x1, y1, x2,y2,...]
 
這個個函數(shù)將src中的坐標映射到dst中的坐標,實現(xiàn)圖像的變換。


具體的例子可以參考APIDemos里的PolyToPoly,我在這里就不再貼代碼了,只講一下函數(shù)是怎么變換圖片的。下面是效果:


圖中寫1的是原圖,寫有2,3,4的是變換后的圖形?,F(xiàn)在分析2是怎么變換來的,變換的原坐標點和目的坐標點如下:
src=new float[] { 32, 32, 64, 32 }
dst=new float[] { 32, 32, 64, 48 }

從上圖標示出的坐標看出原圖的(32,32)映射到原圖的(32,32),(64,32)映射到原圖(64,48)這樣的效果是圖像放大了而且發(fā)生了旋轉(zhuǎn)。這樣的過程相當于(32,32)點不動,然后拉住圖形(64,32)點并拉到(64,48)點處,這樣圖形必然會被拉伸放大并且發(fā)生旋轉(zhuǎn)。最后用一個平移將圖形移動到右邊現(xiàn)在的位置。希望能夠好好理解這一過程,下面的3,4圖是同樣的道理。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    亚洲精品偷拍视频免费观看| 日本高清一道一二三区四五区| 黑人粗大一区二区三区| 欧美不卡高清一区二区三区| 草草视频精品在线观看| 日本亚洲精品在线观看| 最新午夜福利视频偷拍| 欧美三级不卡在线观线看| 国产又粗又猛又大爽又黄| 国产情侣激情在线对白| 欧美亚洲三级视频在线观看| 久草热视频这里只有精品| 激情内射日本一区二区三区| 国产精品一区二区三区日韩av| 欧美成人精品一区二区久久| 黄色片一区二区三区高清| 一区二区欧美另类稀缺| 少妇肥臀一区二区三区| 日韩国产传媒在线精品| 99秋霞在线观看视频| 国产精品成人一区二区三区夜夜夜 | 成年人免费看国产视频| 高清一区二区三区不卡免费| 一区中文字幕人妻少妇| 久久婷婷综合色拍亚洲| 91天堂免费在线观看| 都市激情小说在线一区二区三区| 亚洲三级视频在线观看免费| 欧美成人免费夜夜黄啪啪| 国产精品二区三区免费播放心| 亚洲中文在线中文字幕91| 日本东京热视频一区二区三区| 亚洲一区二区亚洲日本| 国产精品欧美一区二区三区不卡| 男人和女人黄 色大片| 国产精品夜色一区二区三区不卡| 亚洲熟女一区二区三四区| 久久老熟女一区二区三区福利| 色丁香之五月婷婷开心| 欧美日韩中黄片免费看| 久热香蕉精品视频在线播放|