自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

OPhone中的圖片特效處理

移動(dòng)開(kāi)發(fā)
在OPhone編程中有時(shí)候需要對(duì)圖片做特殊的處理,比如將圖片做出黑白的,或者老照片的效果,有時(shí)候還要對(duì)圖片進(jìn)行變換,以拉伸,扭曲等等。

顏色矩陣

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

 

矩陣的運(yùn)算規(guī)則是矩陣A的一行乘以矩陣C的一列作為矩陣R的一行,C矩陣是圖片中包含的ARGB信息,R矩陣是用顏色矩陣應(yīng)用于C之后的新的顏色分量,運(yùn)算結(jié)果如下:#t#
 
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;
 
顏色矩陣并不是看上去那么深?yuàn)W,其實(shí)需要使用的參數(shù)很少,而且很有規(guī)律第一行決定紅色第二行決定綠色,第三行決定藍(lán)色,第四行決定了透明度,第五列是顏色的偏移量。下面是一個(gè)實(shí)際中使用的顏色矩陣。

 

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

 

圖1.5所示矩陣計(jì)算后會(huì)發(fā)現(xiàn)紅色分量增加100,綠色分量增加100,這樣的效果就是圖片偏黃,因?yàn)榧t色和綠色混合后得到黃色,黃色增加了100,圖片當(dāng)然就偏黃了。

 

#p#

改變各顏色分量不僅可以通過(guò)修改第5列的顏色偏移量也可如上面矩陣所示將對(duì)應(yīng)的顏色值乘以一個(gè)倍數(shù),直接放大。上圖1.6是將綠色分量乘以2變?yōu)樵瓉?lái)的2倍。相信讀者至此已經(jīng)明白了如何通過(guò)顏色矩陣來(lái)改變各顏色分量。下面編寫一段代碼來(lái),通過(guò)調(diào)整顏色矩陣來(lái)獲得不同的顏色效果,JavaCode如下:

  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. }    

#p#

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

 

 

 

 


看到這里,相信大家對(duì)顏色矩陣的作用已經(jīng)有了一個(gè)直觀的感受,現(xiàn)在也可以嘗試做一個(gè)照片特效的軟件。但是各種效果并不能讓用戶手動(dòng)調(diào)節(jié)顏色矩陣,這里需要計(jì)算公式,由于本人并不是做圖形軟件的也不能提供,可以參考這個(gè)鏈接:http://www.adobe.com/devnet/flash/articles/matrix_transformations/ColorMatrixDemo.swf  #p#

坐標(biāo)變換矩陣

坐標(biāo)變換矩陣是一個(gè)3*3的矩陣如圖2.1,用來(lái)對(duì)圖形進(jìn)行坐標(biāo)變化,將原來(lái)的坐標(biāo)點(diǎn)轉(zhuǎn)移到新的坐標(biāo)點(diǎn),因?yàn)橐粋€(gè)圖片是有點(diǎn)陣和每一點(diǎn)上的顏色信息組成的,所以對(duì)坐標(biāo)的變換,就是對(duì)每一點(diǎn)進(jìn)行搬移形成新的圖片。具體的說(shuō)圖形的放大縮小,移動(dòng),旋轉(zhuǎn),透視,扭曲這些效果都可以用此矩陣來(lái)完成。 

 

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

 

上圖就是一個(gè)坐標(biāo)變換矩陣的簡(jiǎn)單例子,計(jì)算后發(fā)現(xiàn)x'=x+50,y'=y+50.可見(jiàn)圖片的每一點(diǎn)都在x和y方向上平移到了(50,50)點(diǎn)處,這種效果就是平移效果,將圖片轉(zhuǎn)移到了(50,50)處。

 

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

 


#p#

( , )單位向量 

上面的各種效果也可以疊加在一起,既矩陣的組合變換,可以用矩陣乘法實(shí)現(xiàn)之,如:R=B(A*C)=(B*A)C,注意一點(diǎn)就是B*A和A*B一般是不等的。下面將編一個(gè)小程序,通過(guò)控制坐標(biāo)變換矩陣來(lái)達(dá)到控制圖形的目的,JavaCode如下:

  1. CooMatrix類:     
  2.       
  3. public 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. }     
  51. MyImage類繼承自View類:     
  52. public 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 一個(gè)坐標(biāo)變換矩陣     
  79.         Matrix cm = new Matrix();     
  80. //為坐標(biāo)變換矩陣設(shè)置響應(yīng)的值     
  81.        cm.setValues(array);     
  82. //按照坐標(biāo)變換矩陣的描述繪圖     
  83.         canvas.drawBitmap(mBitmap, cm, paint);     
  84.         Log.i("CMatrix", "--------->onDraw");     
  85.       
  86.             
  87.     }     
  88.         
  89. }    

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

 

 

 

 

上面給出了用坐標(biāo)變換矩陣做出的各種效果,用坐標(biāo)變換矩陣可以方面的調(diào)節(jié)圖形的各種效果,但是我們看看Matrix類就可以發(fā)現(xiàn),實(shí)際上,matrix類本身已經(jīng)提供了許多類似的方法,我們只要調(diào)用,就可以了。#p#

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ù)雜的變換,同時(shí)不必親手去改動(dòng)坐標(biāo)變換矩陣,Matrix類提供了許多Map方法,將原圖形映射到目標(biāo)點(diǎn)構(gòu)成新的圖形,下面簡(jiǎn)述setPolyToPoly(float[] src, int srcIndex, float[] dst, int dstIndex, int pointCount) 的用法,希望起到舉一反三的作用。參數(shù)src和dst是分別存儲(chǔ)了原圖像的點(diǎn)和和指定的目標(biāo)點(diǎn)的一維數(shù)組,數(shù)組中存儲(chǔ)的坐標(biāo)格式如下:
 [x0, y0, x1, y1, x2,y2,...]
 
這個(gè)個(gè)函數(shù)將src中的坐標(biāo)映射到dst中的坐標(biāo),實(shí)現(xiàn)圖像的變換。具體的例子可以參考APIDemos里的PolyToPoly,我在這里就不再貼代碼了,只講一下函數(shù)是怎么變換圖片的。下面是效果:

 

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

 

從上圖標(biāo)示出的坐標(biāo)看出原圖的(32,32)映射到原圖的(32,32),(64,32)映射到原圖(64,48)這樣的效果是圖像放大了而且發(fā)生了旋轉(zhuǎn)。這樣的過(guò)程相當(dāng)于(32,32)點(diǎn)不動(dòng),然后拉住圖形(64,32)點(diǎn)并拉到(64,48)點(diǎn)處,這樣圖形必然會(huì)被拉伸放大并且發(fā)生旋轉(zhuǎn)。最后用一個(gè)平移將圖形移動(dòng)到右邊現(xiàn)在的位置。希望能夠好好理解這一過(guò)程,下面的3,4圖是同樣的道理。Matrix還有許多類似的Map方法可以做出許多效果。詳細(xì)可以參考Matrix類下的方法。

責(zé)任編輯:chenqingxiang 來(lái)源: ophonesdn
相關(guān)推薦

2013-04-22 13:57:15

Android圖像特效

2016-11-09 20:41:47

PHP圖片切片圖片壓縮

2013-01-04 16:17:33

Android開(kāi)發(fā)圖像特效圖像處理

2017-07-13 11:44:20

Web開(kāi)發(fā)CSSPC

2009-06-10 21:48:03

滾動(dòng)圖片Javascript特

2015-07-03 09:37:34

HTML5Figure圖片字幕特效

2010-07-26 14:25:06

Widget開(kāi)發(fā)

2010-07-26 14:44:47

Widget開(kāi)發(fā)

2010-01-05 16:58:43

圖片處理

2010-07-26 15:47:02

Ophone系統(tǒng)

2010-03-04 16:08:21

Android系統(tǒng)平臺(tái)

2010-07-26 12:33:04

控件

2010-07-23 16:08:38

OPhone平臺(tái)

2009-09-08 17:45:13

Ophone Widg

2009-03-28 09:15:45

AndroidGoogle移動(dòng)OS

2010-07-26 12:57:12

OPhone游戲開(kāi)發(fā)

2009-03-26 08:26:22

AndroidGoogle移動(dòng)OS

2020-05-21 10:44:57

CSS混合模式開(kāi)發(fā)

2010-03-09 19:19:40

Python圖像處理

2010-07-23 14:51:09

OPhone開(kāi)發(fā)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)