Android開發(fā)之圖片旋轉(zhuǎn)功能實現(xiàn)方法【基于Matrix】
本文實例講述了Android開發(fā)之圖片旋轉(zhuǎn)功能實現(xiàn)方法。分享給大家供大家參考,具體如下:
在Android中進(jìn)行圖像旋轉(zhuǎn)需要使用Matrix,它包含了一個3*3的矩陣,專門用于進(jìn)行圖像變換匹配。Matrix ,中文里叫矩陣,高等數(shù)學(xué)里有介紹,在圖像處理方面,主要是用于平面的縮放、平移、旋轉(zhuǎn)等操作。Matrix沒有機(jī)構(gòu)體,它必須初始化,然后通過reset方法和set方法來實現(xiàn)。
首先介紹一下矩陣運(yùn)算。加法和減法就不用說了,太簡單了,對應(yīng)位相加就好。圖像處理,主要用到的是乘法 。下面是一個乘法的公式:

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

沒專業(yè)工具,畫的挺難看。解釋一下,上面的 sinX 和 cosX ,表示旋轉(zhuǎn)角度的 cos 值和 sin 值,注意,旋轉(zhuǎn)角度是按順時針方向計算的。 translateX 和 translateY 表示 x 和 y 的平移量。 scale 是縮放的比例, 1 是不變, 2 是表示縮放 1/2,這樣子。
Matrix的操作,總共分為translate(平移),rotate(旋轉(zhuǎn)),scale(縮放)和skew(傾斜)四種,每一種變換在Android的API里都提供了set,post和pre三種操作方式,除了translate,其他三種操作都可以指定中心點。set是直接設(shè)置Matrix的值,每次set一次,整個Matrix的數(shù)組都會變掉。
我們現(xiàn)在通過setRotate設(shè)置旋轉(zhuǎn)角度,用creatBitmap創(chuàng)建一個經(jīng)過旋轉(zhuǎn)等處理的Bitmap對象,然后將Bitmap繪制到屏幕之上,于是就實現(xiàn)了旋轉(zhuǎn)操作。
下面使用一個示例來說明Matix的使用以及旋轉(zhuǎn)的方式及運(yùn)行效果。
package cn.edu.pku;
import android.app.Activity;
import android.os.Bundle;
import android.view.KeyEvent;
public class PictureRotateActivity extends Activity {
/** Called when the activity is first created. */
private GameRotateView1 gameview = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
gameview = new GameRotateView1(this);
setContentView(gameview);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
if ( gameview == null )
{
return false;
}
if ( keyCode == KeyEvent.KEYCODE_BACK)
{
this.finish();
return true;
}
return gameview.onKeyDown(keyCode,event);
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
super.onKeyUp(keyCode, event);
return true;
}
}
具體圖像旋轉(zhuǎn)處理代碼如下:
package cn.edu.pku;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.drawable.BitmapDrawable;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
public class GameRotateView1 extends View implements Runnable {
Bitmap bitmap = null;
int bitmapWidth = 0;
int bitmapHeight = 0;
float angle = 0.0f;
Matrix matrix = new Matrix();
public GameRotateView1(Context context) {
super(context);
// TODO Auto-generated constructor stub
setFocusableInTouchMode(true); //設(shè)置可以捕捉鍵盤事件
//獲取圖像資源
bitmap = ((BitmapDrawable) getResources().getDrawable(R.drawable.cute)).getBitmap();
bitmapWidth = bitmap.getWidth();
bitmapHeight = bitmap.getHeight();
new Thread(this).start();
}
public void run() {
// TODO Auto-generated method stub
while(!Thread.currentThread().isInterrupted()){
try{
Thread.sleep(100);
}catch (InterruptedException e) {
// TODO: handle exception
Thread.currentThread().interrupt();
}
postInvalidate(); //可以直接在線程中更新界面
}
}
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
matrix.reset();
matrix.setRotate(angle); //設(shè)置旋轉(zhuǎn)
//按照matrix的旋轉(zhuǎn)構(gòu)建新的Bitmap
Bitmap bitmapcute = Bitmap.createBitmap(bitmap, 0, 0, bitmapWidth, bitmapHeight, matrix, true);
//繪制旋轉(zhuǎn)之后的圖像
GameRotateView1.DrawImage(canvas, bitmapcute, (320 - bitmapWidth)/2, 10);
bitmapcute = null;
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
if(keyCode == KeyEvent.KEYCODE_DPAD_LEFT){
angle--;
}else if(keyCode == KeyEvent.KEYCODE_DPAD_RIGHT){
angle++;
}
return true;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
return true;
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) {
// TODO Auto-generated method stub
return true;
}
/**
* 繪制一個Bitmap
* canvas 畫布
* bitmap 圖片
* x 屏幕上的x坐標(biāo)
* y 屏幕上的y坐標(biāo)
*/
public static void DrawImage(Canvas canvas, Bitmap _bitmap, int x, int y)
{
/* 繪制圖像 */
canvas.drawBitmap(_bitmap, x, y, null);
}
最后我們通過鍵盤的左右鍵可以實現(xiàn)圖像的選裝,在這里實現(xiàn)的圖像的右旋轉(zhuǎn):

更多關(guān)于Android相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Android圖形與圖像處理技巧總結(jié)》、《Android開發(fā)入門與進(jìn)階教程》、《Android調(diào)試技巧與常見問題解決方法匯總》、《Android基本組件用法總結(jié)》、《Android視圖View技巧總結(jié)》、《Android布局layout技巧總結(jié)》及《Android控件用法總結(jié)》
希望本文所述對大家Android程序設(shè)計有所幫助。
相關(guān)文章
Android系統(tǒng)設(shè)置中的清除數(shù)據(jù)會清除哪些數(shù)據(jù)?
這篇文章主要介紹了Android系統(tǒng)設(shè)置中的清除數(shù)據(jù)會清除哪些數(shù)據(jù)?本文對比了清除前和清除后的數(shù)據(jù)情況,從而得出到底清除了哪些數(shù)據(jù),需要的朋友可以參考下2015-01-01
Android平臺基于Pull方式對XML文件解析與寫入方法詳解
這篇文章主要介紹了Android平臺基于Pull方式對XML文件解析與寫入方法,結(jié)合實例形式分析了Android基于Pull方式對xml文件解析及寫入操作的步驟、原理與操作技巧,需要的朋友可以參考下2016-10-10
Android實現(xiàn)四級聯(lián)動地址選擇器
這篇文章主要為大家詳細(xì)介紹了Android實現(xiàn)四級聯(lián)動地址選擇器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2020-10-10
Android PreferenceActivity與PreferenceFragment詳解及簡單實例
這篇文章主要介紹了Android PreferenceActivity與PreferenceFragment詳解及簡單實例的相關(guān)資料,需要的朋友可以參考下2016-12-12
Android 組件Gallery和GridView示例講解
本文主要講解Android 組件Gallery和GridView,這里詳細(xì)介紹組件Gallery和GridView的知識要點,并附示例代碼和實現(xiàn)效果圖,有興趣的小伙伴可以參考下2016-08-08
android基于SwipeRefreshLayout實現(xiàn)類QQ的側(cè)滑刪除
本篇文章主要介紹了android基于SwipeRefreshLayout實現(xiàn)類QQ的側(cè)滑刪除,非常具有實用價值,需要的朋友可以參考下2017-10-10
Android 多線程實現(xiàn)重復(fù)啟動與停止的服務(wù)
這篇文章主要介紹了Android 多線程實現(xiàn)重復(fù)啟動與停止的服務(wù)的相關(guān)資料,多線程環(huán)境下為了避免死鎖,一般提倡開放調(diào)用,開放調(diào)用可以避免死鎖,它的代價是失去原子性,這里說明重復(fù)啟動與停止的服務(wù),需要的朋友可以參考下2017-08-08
android開發(fā)教程之卸載sd卡對MediaServer的處理
Android中如果MediaServer訪問SD卡上的音頻文件,卸載SD卡的時候,就會kill掉MediaServer,卸載SD卡上必要條件就是沒有進(jìn)程訪問SD卡上的資源文件。Kill掉MediaServer的進(jìn)程后,MediaServer會重新啟動。2014-02-02

