国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android中Matrix用法實例分析

2020-04-11 11:22:24
字體:
來源:轉載
供稿:網友

本文實例講述了Android中Matrix用法。分享給大家供大家參考,具體如下:

Matrix ,中文里叫矩陣,高等數學里有介紹,在圖像處理方面,主要是用于平面的縮放、平移、旋轉等操作。

首先介紹一下矩陣運算。加法和減法就不用說了,對應位相加就好。圖像處理,主要用到的是乘法 。下面是一個乘法的公式:

在 Android 里面, Matrix 由 9 個 float 值構成,是一個 3*3 的矩陣。如下圖:

解釋一下,上面的sinX 和cosX ,表示旋轉角度的cos 值和sin值,注意,旋轉角度是按順時針方向計算的。 translateX 和 translateY 表示 x 和 y 的平移量。 scale 是縮放的比例, 1 是不變, 2 是表示縮放 1/2 。

Matrix的操作,總共分為translate(平移),rotate(旋轉),scale(縮放)和skew(傾斜)四種,每一種變換在Android的API里都提供了set, post和pre三種操作方式,除了translate,其他三種操作都可以指定中心點。

set是直接設置Matrix的值,每次set一次,整個Matrix的數組都會變掉。

post是后乘,當前的矩陣乘以參數給出的矩陣。可以連續多次使用post,來完成所需的整個變換。例如,要將一個圖片旋轉30度,然后平移到(100,100)的地方,那么可以這樣做:Matrix m =  new  Matrix();  m.postRotate(30 );  m.postTranslate(100 ,  100 ); 這樣就達到了想要的效果。

pre是前乘,參數給出的矩陣乘以當前的矩陣。所以操作是在當前矩陣的最前面發生的。例如上面的例子,如果用pre的話,就要這樣:Matrix m =  new  Matrix(); m.setTranslate(100 ,  100 );  m.preRotate(30 );

旋轉、縮放和傾斜都可以圍繞一個中心點來進行,如果不指定,默認情況下,是圍繞(0,0)點來進行。

特別注意:

Matrix的操作,總共分為translate(平移),rotate(旋轉),scale(縮放)和skew(傾斜)四種,每一種變換在Android的API里都提供了set, post和pre三種操作方式,除了translate,其他三種操作都可以指定中心點。

set是直接設置Matrix的值,每次set一次,整個Matrix的數組都會變掉。

post是后乘,當前的矩陣乘以參數給出的矩陣。可以連續多次使用post,來完成所需的整個變換。

鏡面效果:

倒影效果:

圖片的合成(水印):

不多說了,直接上代碼了。

MainActivity.java里的主要代碼如下:

package net.loonggg.testmatrix; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.PorterDuff.Mode; import android.graphics.PorterDuffXfermode; import android.os.Bundle; import android.view.Window; import android.widget.ImageView; public class MainActivity extends Activity {   private ImageView iv1, iv2;   private Canvas canvas;   private Paint paint;   @Override   protected void onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState);     requestWindowFeature(Window.FEATURE_NO_TITLE);     setContentView(R.layout.activity_main);     iv1 = (ImageView) findViewById(R.id.iv1);     iv2 = (ImageView) findViewById(R.id.iv2);     Bitmap bitmap1 = BitmapFactory.decodeResource(getResources(),         R.drawable.weibo);     Bitmap updateBitmap = Bitmap.createBitmap(bitmap1.getWidth() * 2,         bitmap1.getHeight() * 2, bitmap1.getConfig());     canvas = new Canvas(updateBitmap);     paint = new Paint();     paint.setColor(Color.BLACK);     Matrix matrix = new Matrix();     // setMirrorOne(bitmap1, matrix);     // setInvertedImage(bitmap1, matrix);     // setBaseChange(matrix);     canvas.drawBitmap(bitmap1, matrix, paint);     setImageSynthesis(matrix);     iv1.setImageBitmap(bitmap1);     iv2.setImageBitmap(updateBitmap);   }   /**    * 還有一些基本變化    */   private void setBaseChange(Matrix matrix) {     // matrix.setRotate(60);// 這是旋轉多少度     // matrix.setRotate(degrees, px, py);//這個方法是以哪個點為中心進行旋轉多少度     // matrix.setSkew(kx, ky);//設置傾斜,以x軸傾斜,還是y軸     // 傾斜x和y軸,以(100,100)為中心。     // matrix.postSkew(0 .2f, 0 .2f, 100 , 100 );     // matrix.setScale(0.5f, 1);//縮放寬度變為原來的一半,高度不變   }   /**    * 設置倒影效果    *    * @param bitmap1    * @param matrix    */   private void setInvertedImage(Bitmap bitmap1, Matrix matrix) {     matrix.setScale(1, -1);     matrix.postTranslate(0, bitmap1.getHeight());   }   /**    * 設置鏡面效果方法一    *    * @param bitmap1    * @param matrix    */   private void setMirrorOne(Bitmap bitmap1, Matrix matrix) {     matrix.setTranslate(bitmap1.getWidth(), 0);// 這個是移動     matrix.preScale(-1, 1);   }   // ---------------------------------------------------------   /**    * 解釋:鏡面效果方法一和二的區別:    * 不知道大家看沒看出來,其實這兩種方法的效果是一樣的,只不過是設置步驟不一樣,post是后乘,當前的矩陣乘以參數給出的矩陣    * 。可以連續多次使用post,來完成所需的整個變換。 pre是前乘,參數給出的矩陣乘以當前的矩陣。所以操作是在當前矩陣的最前面發生的。    * 可以連續多次使用post    * ,來完成所需的整個變換,但是不可以連續使用set來完成矩陣的整個變換,為什么呢?set是直接設置Matrix的值,每次set一次    * ,整個Matrix的數組都會變掉,第一次可以使用set,之后的變換必須換成post或者pre,也可以一直用post也行    */   // ---------------------------------------------------------   /**    * 設置鏡面效果方法二    *    * @param bitmap1    * @param matrix    */   private void setMirrorTwo(Bitmap bitmap1, Matrix matrix) {     matrix.setScale(-1, 1);     matrix.postTranslate(bitmap1.getWidth(), 0);   }   /**    * 設置圖片的合成    *    * @param matrix    */   private void setImageSynthesis(Matrix matrix) {     Bitmap bitmap2 = BitmapFactory.decodeResource(getResources(),         R.drawable.ic_launcher);     // 設置圖片合成時的各種模式     paint.setXfermode(new PorterDuffXfermode(Mode.DARKEN));     // 圖片的合成很簡單,就是再以bitmap2為基圖往目標圖片上畫一次     canvas.drawBitmap(bitmap2, matrix, paint);   } }

布局文件的代碼如下:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"   xmlns:tools="http://schemas.android.com/tools"   android:layout_width="match_parent"   android:layout_height="match_parent"   android:orientation="vertical"   tools:context=".MainActivity" >   <ImageView     android:id="@+id/iv1"     android:layout_width="wrap_content"     android:layout_height="wrap_content" />   <ImageView     android:id="@+id/iv2"     android:layout_width="wrap_content"     android:layout_height="wrap_content" /> </LinearLayout>

希望本文所述對大家Android程序設計有所幫助。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 新兴县| 洪湖市| 商丘市| 宜章县| 大邑县| 喀喇沁旗| 洪湖市| 府谷县| 宜兰县| 英山县| 连州市| 名山县| 同德县| 筠连县| 花垣县| 乌兰察布市| 鹤峰县| 磐石市| 班玛县| 石楼县| 合川市| 洪泽县| 永平县| 紫阳县| 永德县| 营山县| 攀枝花市| 西和县| 出国| 博湖县| 陇西县| 勐海县| 广德县| 呼玛县| 五华县| 砚山县| 商南县| 子洲县| 衡东县| 永修县| 乌兰浩特市|