日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android变形(Transform)之Camera使用介绍【转】

發(fā)布時間:2023/12/18 Android 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android变形(Transform)之Camera使用介绍【转】 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

接Android變形(Transform)之Matrix,來總結下Camera的使用,Camera主要實現(xiàn)3D的變形,有轉(zhuǎn)動,旋轉(zhuǎn)等,Camera的源碼是由Native(本地代碼)實現(xiàn),提供的接口也比較簡單。官方的介紹:A camera instance can be used to compute 3D transformations and generate a matrix that can be applied, for instance, on a?Canvas.

效果圖

原圖:

變形以后:

?

API使用

Camera提供的方法如下:

save:保存當前狀態(tài)

restore:回復當前狀態(tài)

translate:在x,y,z三位控件內(nèi)進行平移

rotateX:以(0.0)為中心,繞X軸進行選擇

rotateY:以(0.0)為中心,繞Y軸進行選擇

rotateZ:以(0.0)為中心,旋轉(zhuǎn)(此處和Matrix旋轉(zhuǎn)原理一樣,只不過反向相反,為逆時針)

...

常用的就這么多

實踐

直接上代碼:

復制代碼代碼如下:
public class CameraTransformView extends View {?

private Bitmap mBitmap;?
private Camera mCamera;?
private Matrix mMatrix;?
private int deltaX, deltaY, deltaZ, extraZ;?
private int centerX, centerY;?

public CameraTransformView(Context context, AttributeSet attrs) {?
super(context, attrs);?
}?

public void setDrawable(int resId) {?
mBitmap = BitmapFactory.decodeResource(getResources(), resId);?
centerX = mBitmap.getWidth() / 2;?
centerY = mBitmap.getHeight() / 2;?
mCamera = new Camera();?
mMatrix = new Matrix();?
}?

public void setDelta(int x, int y, int z, int extra) {?
deltaX += x;?
deltaY += y;?
deltaZ += z;?
extraZ += extra;?
invalidate();?
}?

public void reset() {?
deltaX = 0;?
deltaY = 0;?
deltaZ = 0;?
invalidate();?
}?

@Override?
protected void onDraw(Canvas canvas) {?
mCamera.save();?
mCamera.translate(10, 10, extraZ);?
mCamera.rotateX(deltaX);?
mCamera.rotateY(deltaY);?
mCamera.rotateZ(deltaZ);?
mCamera.getMatrix(mMatrix);?
mCamera.restore();?

mMatrix.preTranslate(-this.centerX, -this.centerY);?
mMatrix.postTranslate(this.centerX, this.centerY);?

canvas.drawBitmap(mBitmap, mMatrix, null);?
super.onDraw(canvas);?
}?

}


其實Camera的變化就是封裝了一個Matrix矩陣,可以通過getMatrix方法來獲取這個坐標矩陣。在上面的Demo中就用到了該方法做些額外的處理,下面具體看看:?

復制代碼代碼如下:
@Override?
protected void onDraw(Canvas canvas) {?
mCamera.save();?
mCamera.translate(10, 10, extraZ);?
mCamera.rotateX(deltaX);?
mCamera.rotateY(deltaY);?
mCamera.rotateZ(deltaZ);?
mCamera.getMatrix(mMatrix);?
mCamera.restore();?

//mMatrix.preTranslate(-this.centerX, -this.centerY);?
//mMatrix.postTranslate(this.centerX, this.centerY);?

canvas.drawBitmap(mBitmap, mMatrix, null);?
super.onDraw(canvas);?
}


在onDraw方法中,可以通過Camera的方法來完成變形。注意11,12行,如果在onDraw的時候不進行倆行設置的話,可以看到效果如下:

?

可以看到,其按照Y軸旋轉(zhuǎn)中心點是(0,0),那么平常的應用而言,大多希望其中心點在圖片的中心點上。所以需要加入?

復制代碼代碼如下:
mMatrix.preTranslate(-this.centerX, -this.centerY);?
mMatrix.postTranslate(this.centerX, this.centerY);


其實這一節(jié)的重點就在于剖析這倆句話。

?

從Camara的API中可以看出來其不提供變形中心點的設置方法,那么怎么辦呢,基本思路是:假設圖片中心點為(centerX,centerY),既然Camera始終以(0,0)為中心點,那么我先將圖形矩陣往左移動centerX,再往上移動centerY,讓(centerX,centerY)正好掐在初始的(0,0)上,這樣進行變形的話,中心點就變成了(centerX,centerY),達到了目的,當然這還沒結束,你既然偏移了(-centerX,-centerY),那么變形以后得移回來,然后再往右下方分別移動centerX,centerY。

按照矩陣的變換,可以表達為:

1,0,-centerX 1,0,centerX

0,1,-centerY * 變形矩陣 * 0,1,centerY

0,0,1 0,0,1

那么具體就如此,思路和代碼結合起來怎么來解釋呢,接著看,我們需要回顧下Matrix中的部分知識。

回顧

Matrix提供的三種變形方式為:set,post,pre。

set就是先reset,然后進行變形

pre可以解釋為先乘,在矩陣原理中對應的右乘

post可以理解成后乘,在矩陣遠離中對應左乘

不著急,接下倆具體看什么是先乘,后乘,什么是左乘,右乘。

舉個例子:

原圖

讓一個圖形按照中心點放大至2倍

那么期望的效果是:中心點不變(圖片被邊緣截斷了)

那么按照之前提高的思路:假設中心點是(50,50)先左上移50,也即(-50,-50)再進行放大,再右下移50,也即(50,50)

api調(diào)用即為:setScale(2,2), preTranslate(-50,-50), postTranslate(50,50)

照例來說對應矩陣為:

1,0,-50 2,0,0 1,0,50 2,0,50

0,1,-50 * 0,0,2 * 0,1,50 = 0,2,50

0,0,1 0,0,1 0,0,1 0,0,1

可以看到結果是放大至2倍,但是卻往右下移動了(50,50),奇怪要是這樣的話,和預期的效果圖一樣預期的效果圖矩陣應該為(方法至2倍,往左上移動(-50,-50))

2,0,-50

0,2,-50,

0,0,1

好,揭曉下疑點:

此處api的執(zhí)行順序為:preTranslate(-50,-50) -> setScale(2,2) -> postTranslate(50,50) 沒有問題

答案揭曉:矩陣符合變化的原則,如果圖形經(jīng)過F1,F2...Fn此變形,對應矩陣為T1,T2...Tn,符合矩陣T = Tn*Tn-1...*T1

那么正確的矩陣算法應該為

1,0,50 2,0,0 1,0,-50 2,0,-50

0,1,50 * 0,0,2 * 0,1,-50 = 0,2,-50

0,0,1 0,0,1 0,0,1 0,0,1

?

此處也解釋了pre為右乘,post為左乘的原理了。

那么到此為止,一切都都得到了解釋。

回歸

回歸到Camera的Demo當中,既然Camera的變形中心點是(0,0),而且Camera的變形實際是對Matrix的變形,我們可以通過getMatrix方法來獲取這個Matrix,然后通過左移pre,變形后右移post來實現(xiàn)中心點的設置。

?

轉(zhuǎn)載于:https://www.cnblogs.com/liyingming/archive/2013/04/05/3001561.html

總結

以上是生活随笔為你收集整理的Android变形(Transform)之Camera使用介绍【转】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。