1. 程式人生 > >Android中影象變換Matrix的原理應用

Android中影象變換Matrix的原理應用

第一部分 Matrix的數學原理

在Android中,如果你用Matrix進行過影象處理,那麼一定知道Matrix這個類。Android中的Matrix是一個3 x 3的矩陣,其內容如下:

 

Matrix的對影象的處理可分為四類基本變換:

Translate           平移變換

Rotate                旋轉變換

Scale                  縮放變換

Skew                  錯切變換

從字面上理解,矩陣中的MSCALE用於處理縮放變換,MSKEW用於處理錯切變換,MTRANS用於處理平移變換,MPERSP用於處理透視變換。實際中當然不能完全按照字面上的說法去理解Matrix。同時,在Android的文件中,未見到用Matrix進行透視變換的相關說明,所以本文也不討論這方面的問題。

針對每種變換,Android提供了pre、set和post三種操作方式。其中

set用於設定Matrix中的值。

pre是先乘,因為矩陣的乘法不滿足交換律,因此先乘、後乘必須要嚴格區分。先乘相當於矩陣運算中的右乘。

post是後乘,因為矩陣的乘法不滿足交換律,因此先乘、後乘必須要嚴格區分。後乘相當於矩陣運算中的左乘。

除平移變換(Translate)外,旋轉變換(Rotate)、縮放變換(Scale)和錯切變換(Skew)都可以圍繞一箇中心點來進行,如果不指定,在預設情況下是圍繞(0, 0)來進行相應的變換的。

下面我們來看看四種變換的具體情形。由於所有的圖形都是有點組成,因此我們只需要考察一個點相關變換即可。

一、 平移變換

假定有一個點的座標是 ,將其移動到 ,再假定在x軸和y軸方向移動的大小分別為:


如下圖所示:


不難知道:


如果用矩陣來表示的話,就可以寫成:

 

二、 旋轉變換

2.1    圍繞座標原點旋轉:

假定有一個點 ,相對座標原點順時針旋轉後的情形,同時假定P點離座標原點的距離為r,如下圖:


那麼,


如果用矩陣,就可以表示為:


2.2    圍繞某個點旋轉

如果是圍繞某個點順時針旋轉,那麼可以用矩陣表示為:


可以化為:


很顯然,

1.   

  是將座標原點移動到點後, 的新座標。

2.     


是將上一步變換後的,圍繞新的座標原點順時針旋轉 。

3.     


經過上一步旋轉變換後,再將座標原點移回到原來的座標原點。

所以,圍繞某一點進行旋轉變換,可以分成3個步驟,即首先將座標原點移至該點,然後圍繞新的座標原點進行旋轉變換,再然後將座標原點移回到原先的座標原點。

三、 縮放變換

理論上而言,一個點是不存在什麼縮放變換的,但考慮到所有影象都是由點組成,因此,如果影象在x軸和y軸方向分別放大k1k2倍的話,那麼影象中的所有點的x座標和y座標均會分別放大k1k2倍,即


用矩陣表示就是:


縮放變換比較好理解,就不多說了。

四、 錯切變換

錯切變換(skew)在數學上又稱為Shear mapping(可譯為“剪下變換”)或者Transvection(縮並),它是一種比較特殊的線性變換。錯切變換的效果就是讓所有點的x座標(或者y座標)保持不變,而對應的y座標(或者x座標)則按比例發生平移,且平移的大小和該點到x軸(或y軸)的垂直距離成正比。錯切變換,屬於等面積變換,即一個形狀在錯切變換的前後,其面積是相等的。

比如下圖,各點的y座標保持不變,但其x座標則按比例發生了平移。這種情況將水平錯切。


下圖各點的x座標保持不變,但其y座標則按比例發生了平移。這種情況叫垂直錯切。

 

假定一個點經過錯切變換後得到,對於水平錯切而言,應該有如下關係:


用矩陣表示就是:


擴充套件到3 x 3的矩陣就是下面這樣的形式:

 

同理,對於垂直錯切,可以有:


在數學上嚴格的錯切變換就是上面這樣的。在Android中除了有上面說到的情況外,還可以同時進行水平、垂直錯切,那麼形式上就是:


五、 對稱變換

除了上面講到的4中基本變換外,事實上,我們還可以利用Matrix,進行對稱變換。所謂對稱變換,就是經過變化後的影象和原影象是關於某個對稱軸是對稱的。比如,某點 經過對稱變換後得到

如果對稱軸是x軸,難麼,


用矩陣表示就是:


如果對稱軸是y軸,那麼,


用矩陣表示就是:


如果對稱軸是y = x,如圖:


那麼,


很容易可以解得:


用矩陣表示就是:


同樣的道理,如果對稱軸是y = -x,那麼用矩陣表示就是:

 

特殊地,如果對稱軸是y = kx,如下圖:


那麼,


很容易可解得:


用矩陣表示就是:


k = 0時,即y = 0,也就是對稱軸為x軸的情況;當k趨於無窮大時,即x = 0,也就是對稱軸為y軸的情況;當k =1時,即y = x,也就是對稱軸為y = x的情況;當k = -1時,即y = -x,也就是對稱軸為y = -x的情況。不難驗證,這和我們前面說到的4中具體情況是相吻合的。

如果對稱軸是y = kx + b這樣的情況,只需要在上面的基礎上增加兩次平移變換即可,即先將座標原點移動到(0, b),然後做上面的關於y = kx的對稱變換,再然後將座標原點移回到原來的座標原點即可。用矩陣表示大致是這樣的:


需要特別注意:在實際程式設計中,我們知道螢幕的y座標的正向和數學中y座標的正向剛好是相反的,所以在數學上y = x和螢幕上的y = -x才是真正的同一個東西,反之亦然。也就是說,如果要使圖片在螢幕上看起來像按照數學意義上y = x對稱,那麼需使用這種轉換:


要使圖片在螢幕上看起來像按照數學意義上y = -x對稱,那麼需使用這種轉換:
 

關於對稱軸為y = kx y = kx + b的情況,同樣需要考慮這方面的問題。

第二部分 程式碼驗證

在第一部分中講到的各種影象變換的驗證程式碼如下,一共列出了10種情況。如果要驗證其中的某一種情況,只需將相應的程式碼反註釋即可。試驗中用到的圖片:


其尺寸為162 x 251。

每種變換的結果,請見程式碼之後的說明。

  1. <span style="font-size:13px;"></span><pre name="code"class="java">package com.pat.testtransformmatrix;  
  2. import android.app.Activity;  
  3. import android.content.Context;  
  4. import android.graphics.Bitmap;  
  5. import android.graphics.BitmapFactory;  
  6. import android.graphics.Canvas;  
  7. import android.graphics.Matrix;  
  8. import android.os.Bundle;  
  9. import android.util.Log;  
  10. import android.view.MotionEvent;  
  11. import android.view.View;  
  12. import android.view.Window;  
  13. import android.view.WindowManager;  
  14. import android.view.View.OnTouchListener;  
  15. import android.widget.ImageView;  
  16. publicclass TestTransformMatrixActivity extends Activity  
  17. implements
  18. OnTouchListener  
  19. {  
  20.     private TransformMatrixView view;  
  21.     @Override
  22.     publicvoid onCreate(Bundle savedInstanceState)  
  23.     {  
  24.         super.onCreate(savedInstanceState);  
  25.         requestWindowFeature(Window.FEATURE_NO_TITLE);  
  26.         this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);  
  27.         view = new TransformMatrixView(this);  
  28.         view.setScaleType(ImageView.ScaleType.MATRIX);  
  29.         view.setOnTouchListener(this);  
  30.         setContentView(view);  
  31.     }  
  32.     class TransformMatrixView extends ImageView  
  33.     {  
  34.         private Bitmap bitmap;  
  35.         private Matrix matrix;  
  36.         public TransformMatrixView(Context context)  
  37.         {  
  38.             super(context);  
  39.             bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.sophie);  
  40.             matrix = new Matrix();  
  41.         }  
  42.         @Override
  43.         protectedvoid onDraw(Canvas canvas)  
  44.         {  
  45.             // 畫出原影象
  46.             canvas.drawBitmap(bitmap, 00null);  
  47.             // 畫出變換後的影象
  48.             canvas.drawBitmap(bitmap, matrix, null);  
  49.             super.onDraw(canvas);  
  50.         }  
  51.         @Override
  52.         publicvoid setImageMatrix(Matrix matrix)  
  53.         {  
  54.             this.matrix.set(matrix);  
  55.             super.setImageMatrix(matrix);  
  56.         }  
  57. 相關推薦

    Android影象變換Matrix原理應用

    第一部分 Matrix的數學原理 在Android中,如果你用Matrix進行過影象處理,那麼一定知道Matrix這個類。Android中的Matrix是一個3 x 3的矩陣,其內容如下:   Matrix的對影象的處理可分為四類基本變換: T

    Android外掛開發篇之----應用換膚原理解析

    一、前言今天又到週末了,感覺時間過的很快呀.又要寫blog了。那麼今天就來看看應用的換膚原理解析。在之前的一篇部落格中我說道了Android中的外掛開發篇的基礎:類載入器的相關知識。沒看過的同學可以轉戰:二、原理介紹現在市場上有很多應用都有換膚的功能,就是能夠提供給使用者一些

    Android單例模式的應用

    單例模式在我們日常開發中或多或少都會遇見,使用場景也是多種多樣。今天根據專案中需求,正好用到了單例模式。在此記錄一下。 一、跟隨app存活 有什麼方式,可以讓一個變數跟隨app存活呢?是一個單例模式維護的靜態工具類。靜態工具類程式碼一般都使用單例模式來實現,可以防止建立多

    androidstagefright和OMXCodec原理分析

    1. 框架結構 1.1StageFright和openCore和NuPlayer的關係 上圖可知,stagefright是在MediaPlayerService這一層加入的,和opencZ喎�"/kf/ware/vc/" target="_blank" class=

    原始碼解析AndroidAsyncTask的工作原理

    在之前的部落格《Android中AsyncTask使用詳解》中我們提到AsyncTask是對Thread和Handler的組合包裝,本文將通過解析的方式讓大家瞭解AsyncTask的工作原理。 AsyncTask一開始定義了一些欄位,如下所示: pr

    Android實現多Tab頁應用

    Android上的多Tab是一個什麼效果?如果圖片看不懂的話,但是使用過Android的微部落格戶端,那也很清晰了,就是那個樣子。 但是在Android API V4版本之後,TabActivity被廢棄了不推薦使用,被替換為Fragment, FragmentActivity了,使用新的API

    Android三級快取實現原理及LruCache 原始碼分析

    介紹 oom異常:大圖片導致 圖片的三級快取:記憶體、磁碟、網路 下面通過一張圖來了解下三級快取原理: 程式碼: public class Davince { //使用固定執行緒池優化 private static Exec

    Android典型的ROOT原理(5)

    ROOT的作用 Customization 使用者的個人定製,如刪除一些預安裝,定製開機動畫等. 特權操作 所有需要特權操作的基本都是要通過ROOT,這也是ROOT的初衷. ROOT的第一步:尋找漏洞並安裝特權檔案 Hacker會尋找漏洞,如UID設定失敗(ADB) 手機ROOT後,最重要

    android imageview 與diallog綜合應用猜牌遊戲

    package training.android.com; import android.app.Activity;import android.app.AlertDialog;import android.app.Dialog;import android.content.

    Androidcanvas畫圖的簡單應用

    在最近的Android的實驗中用到了繪製圖形,於是簡單的學習了一下利用canvas進行2D圖形的簡單繪製,一下是個人的總結,以便日後翻看。 其中,有三個重要的東西: Bitmap、Canvas、Paint 以實際生活中的繪畫過程進行類比的話,更容易理解: 1.Bitmap

    AndroidAppWidget的分析與應用:AppWidgetProvider

    2012-8-20本文從開發AppWidgetProvider角度出發,看一個AppWidgetPrvodier在整個AppWidget體系中所扮演的角色。分析了AppWidgetProvider如何被AppWidget系統所識別;AppWidgetProvider何時/如何

    android利用java反射原理將物件新增到sqlit資料庫的萬能方法

    利用java的反射機制,我們可以得到物件裡的方法列表,引數列表以及對應的值,那麼我們就可以利用這些做一個萬能的插入資料庫的方法。 以下方法中表名要和資料庫名一致。  protected void insert(Object ob){ContentValues initia

    AndroidscrollView的滑動原理

    android中所有View都是可以滑動的,其實所有的View都有兩套座標系,一個是指定View位置的X,Y,另一對則是指定View滑動座標系,mScrollX和mScrollY,兩對座標系統是完全獨立的,即X,Y座標的改變不會影響mScrollX和mScrollY,反之也

    Android的動畫和原理(屬性動畫)

    1、屬性動畫 屬性動畫通過改變物件的屬性來展示的動畫效果,補間動畫只是設定當前View在區域內移動,產生的動畫效果,其實原View的還在原地,沒有發生改變。 但屬性動畫改變了物件的屬性。也就是改變了物件的顏色,位置,寬高等。 2、示例 publi

    Android 獲取已經安裝的應用列表

    1、獲取系統應用資訊 private void getPackages() { // 獲取已經安裝的所有應用, PackageInfo 系統類,包含應用資訊 Lis

    Android 的dm-verity原理分析

    Android 中的Verified Boot之dm-verity 之前做了一個Verified Boot模組相關的工作,但是在網上只有找到google的文件和一個nexus的patch。雖然有patch,但在不同版本的程式碼上實現起來卻可能有一些bug,所以特此記錄一下debug這個東西的過程

    androidMap和HashMap的應用

    雜湊表(HashMap)是種資料結構,應用於鍵值對的儲存和查詢,刪除等操作【用來索引的物件叫做key(鍵),其對應的物件叫做value(值)】它可以提供快速的插入操作和查詢操作。第一次接觸雜湊表時,它的優點多得讓人難以置信。不論雜湊表中有多少資料,插入和刪除(

    Android字元裝置驅動和應用例項(一)——驅動部分

     下面介紹建立Android裝置對應的字元裝置驅動 1 字元驅動 在此示例中,我們將字元驅動新增到drivers/char目錄下。 (1)字元驅動的路徑如下: drivers/char/class_reg_unreg.c (2)字元驅動的內容如下: View C

    Android關於如何限制上層應用只在特定區間畫圖

    https roi surf cpp isp 有時 per eth 橫屏 Android中關於如何限制上層應用只在特定區間畫圖 有時候對於mtk開發中有一個很特殊的需求。那就是mtk的手機平臺不支持橫屏模式的display panel屏幕,只支持豎屏。mtk的平板平臺才支持

    Android的LruCache的原理和使用

    # Android中的LruCache的原理和使用 LruCache,雖然很多文章都把LRU翻譯成“最近最少使用”快取策略,但Android中的LruCache真的如此嗎? 答案是No,它只做到了控制“最近使用”! ## 原理 ### 資料結構 LruCache採用LinkedHashMap作為儲存的資料結構