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軸方向分別放大k1和k2倍的話,那麼影象中的所有點的x座標和y座標均會分別放大k1和k2倍,即
用矩陣表示就是:
縮放變換比較好理解,就不多說了。
四、 錯切變換
錯切變換(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。
每種變換的結果,請見程式碼之後的說明。
- <span style="font-size:13px;"></span><pre name="code"class="java">package com.pat.testtransformmatrix;
- import android.app.Activity;
- import android.content.Context;
- import android.graphics.Bitmap;
- import android.graphics.BitmapFactory;
- import android.graphics.Canvas;
- import android.graphics.Matrix;
- import android.os.Bundle;
- import android.util.Log;
- import android.view.MotionEvent;
- import android.view.View;
- import android.view.Window;
- import android.view.WindowManager;
- import android.view.View.OnTouchListener;
- import android.widget.ImageView;
- publicclass TestTransformMatrixActivity extends Activity
- implements
- OnTouchListener
- {
- private TransformMatrixView view;
- @Override
- publicvoid onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- requestWindowFeature(Window.FEATURE_NO_TITLE);
- this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
- view = new TransformMatrixView(this);
- view.setScaleType(ImageView.ScaleType.MATRIX);
- view.setOnTouchListener(this);
- setContentView(view);
- }
- class TransformMatrixView extends ImageView
- {
- private Bitmap bitmap;
- private Matrix matrix;
- public TransformMatrixView(Context context)
- {
- super(context);
- bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.sophie);
- matrix = new Matrix();
- }
- @Override
- protectedvoid onDraw(Canvas canvas)
- {
- // 畫出原影象
- canvas.drawBitmap(bitmap, 0, 0, null);
- // 畫出變換後的影象
- canvas.drawBitmap(bitmap, matrix, null);
- super.onDraw(canvas);
- }
- @Override
- publicvoid setImageMatrix(Matrix matrix)
- {
- this.matrix.set(matrix);
- super.setImageMatrix(matrix);
- }
-
相關推薦
Android中影象變換Matrix的原理應用
第一部分 Matrix的數學原理 在Android中,如果你用Matrix進行過影象處理,那麼一定知道Matrix這個類。Android中的Matrix是一個3 x 3的矩陣,其內容如下: Matrix的對影象的處理可分為四類基本變換: T
Android中外掛開發篇之----應用換膚原理解析
一、前言今天又到週末了,感覺時間過的很快呀.又要寫blog了。那麼今天就來看看應用的換膚原理解析。在之前的一篇部落格中我說道了Android中的外掛開發篇的基礎:類載入器的相關知識。沒看過的同學可以轉戰:二、原理介紹現在市場上有很多應用都有換膚的功能,就是能夠提供給使用者一些
Android中單例模式的應用
單例模式在我們日常開發中或多或少都會遇見,使用場景也是多種多樣。今天根據專案中需求,正好用到了單例模式。在此記錄一下。 一、跟隨app存活 有什麼方式,可以讓一個變數跟隨app存活呢?是一個單例模式維護的靜態工具類。靜態工具類程式碼一般都使用單例模式來實現,可以防止建立多
android中stagefright和OMXCodec原理分析
1. 框架結構 1.1StageFright和openCore和NuPlayer的關係 上圖可知,stagefright是在MediaPlayerService這一層加入的,和opencZ喎�"/kf/ware/vc/" target="_blank" class=
原始碼解析Android中AsyncTask的工作原理
在之前的部落格《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.
Android中canvas畫圖的簡單應用
在最近的Android的實驗中用到了繪製圖形,於是簡單的學習了一下利用canvas進行2D圖形的簡單繪製,一下是個人的總結,以便日後翻看。 其中,有三個重要的東西: Bitmap、Canvas、Paint 以實際生活中的繪畫過程進行類比的話,更容易理解: 1.Bitmap
Android中AppWidget的分析與應用:AppWidgetProvider
2012-8-20本文從開發AppWidgetProvider角度出發,看一個AppWidgetPrvodier在整個AppWidget體系中所扮演的角色。分析了AppWidgetProvider如何被AppWidget系統所識別;AppWidgetProvider何時/如何
android中利用java反射原理將物件新增到sqlit資料庫的萬能方法
利用java的反射機制,我們可以得到物件裡的方法列表,引數列表以及對應的值,那麼我們就可以利用這些做一個萬能的插入資料庫的方法。 以下方法中表名要和資料庫名一致。 protected void insert(Object ob){ContentValues initia
Android中scrollView的滑動原理
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這個東西的過程
android中Map和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作為儲存的資料結構