Android自定義相機(jī)聚焦和顯示框
本文實(shí)例為大家分享了Android自定義相機(jī)聚焦和顯示框的具體代碼,供大家參考,具體內(nèi)容如下
先看使用效果,白色圓框,放大后縮寫并變淡隱藏

下面是代碼
public class CameraFocusView extends AppCompatImageView {
String TAG = getClass().getName();
//顯示的圓寬顯示的位置
public float currnetX = 40;
public float currentY = 50;
Paint paint;
//半徑大小
float radis = 100;
//透明度
int alpha = 255;
boolean isAlpha = false;
private ValueAnimator scaleAnimator,colorAnimator;
public CameraFocusView(Context context) {
super(context);
init();
}
public CameraFocusView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public CameraFocusView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
public void init() {
scaleAnimator = new ValueAnimator();
scaleAnimator.setFloatValues(80, 70, 90);
scaleAnimator.setDuration(500);
scaleAnimator.setInterpolator(new LinearInterpolator());
//伸縮動(dòng)畫效果
scaleAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
radis = (float) animation.getAnimatedValue();
invalidate();
if (radis == 90){
isAlpha = true;
colorAnimator.start();
}
}
});
colorAnimator = new ValueAnimator();
colorAnimator.setIntValues(255,0);
colorAnimator.setDuration(3000);
colorAnimator.setInterpolator(new LinearInterpolator());
//顯示透明度動(dòng)畫效果
colorAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
alpha = (int) animation.getAnimatedValue();
invalidate();
}
});
//初始化不顯示
setVisibility(GONE);
}
//開始現(xiàn)在圓框
public void startAnimator() {
isAlpha = false;
if (scaleAnimator != null) {
Log.e(TAG, "startAnimator: scaleAnimator != null");
setVisibility(VISIBLE);
scaleAnimator.start();
} else {
Log.e(TAG, "startAnimator: scaleAnimator == null");
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//畫筆設(shè)置
paint = new Paint();
paint.setStyle(Paint.Style.STROKE);//畫筆屬性是空心圓
paint.setStrokeWidth(2);//設(shè)置畫筆粗細(xì)
// 抗鋸齒
paint.setAntiAlias(true);
paint.setColor(Color.WHITE);
paint.setAlpha(255);
if (isAlpha){
if (alpha > 0 && alpha < 155){
paint.setAlpha(155);
}else if (alpha == 0){
setVisibility(GONE);
}
}
canvas.drawCircle(currnetX, currentY, radis, paint);
}
}
主界面圖

調(diào)用方式,點(diǎn)擊屏幕就能顯示
public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback, Camera.PreviewCallback{
String TAG = getClass().getName();
SurfaceView surfaceview;
SurfaceHolder surfaceHolder;
Camera camera;
AutoFocusCallBackClass autoFocusCallBackClass;
CameraFocusView cameraFocusView;
SensorControler sensorControler;
int width = 480;
int height = 800;
int surfaceViewWidth = 480;
int surfaceViewHeight = 800;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ConstraintLayout root = findViewById(R.id.root);
surfaceview = findViewById(R.id.surfaceview);
surfaceHolder = surfaceview.getHolder();
Display display = getWindowManager().getDefaultDisplay();
width = display.getWidth();
height = display.getHeight();
cameraFocusView = new CameraFocusView(this);
cameraFocusView.setMinimumWidth(width);
cameraFocusView.setMinimumHeight(height);
root.addView(cameraFocusView);
surfaceview.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
float reax = motionEvent.getX();
float reay = motionEvent.getY();
focusTouch(reax,reay);
return false;
}
});
surfaceHolder.addCallback(this);
}
@Override
protected void onStart() {
super.onStart();
if (sensorControler != null){
sensorControler.start();
}
}
@Override
protected void onStop() {
super.onStop();
if (sensorControler != null){
sensorControler.stop();
}
}
public void focusTouch(float reac_x, float reac_y){
int areaX = (int)(reac_x / surfaceview.getWidth() * 2000) - 1000;
int areaY = (int)(reac_y / surfaceview.getHeight() * 2000) - 1000;
if (camera == null){
return;
}
Camera.Parameters parameters = camera.getParameters();
if (parameters == null){
return;
}
//創(chuàng)建Rect區(qū)域
Rect focusArea = new Rect();
focusArea.left = Math.max(areaX -100,-1000);
focusArea.top = Math.max(areaY - 100,-1000);
focusArea.right = Math.min(areaX + 100,1000);
focusArea.bottom = Math.min(areaY + 100,1000);
// Log.e(TAG, "onTouch: left = " + focusArea.left + " top = " + focusArea.top + " right = " + focusArea.right + " bottom = " + focusArea.bottom);
//創(chuàng)建Camera.Area
Camera.Area cameraArea = new Camera.Area(focusArea,100);
List<Camera.Area> mereringAreas = new ArrayList<>();
List<Camera.Area> focusAreas = new ArrayList<>();
if (parameters.getMaxNumMeteringAreas() > 0){
mereringAreas.add(cameraArea);
focusAreas.add(cameraArea);
}
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
parameters.setFocusAreas(focusAreas);
parameters.setMeteringAreas(mereringAreas);
try {
camera.cancelAutoFocus();
camera.setParameters(parameters);
}catch (Exception e){
e.printStackTrace();
}
if (cameraFocusView != null) {
cameraFocusView.currnetX = reac_x;
cameraFocusView.currentY = reac_y;
cameraFocusView.startAnimator();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
Toast.makeText(this,"ok",Toast.LENGTH_SHORT).show();
initCamera();
}else {
Toast.makeText(this,"no",Toast.LENGTH_SHORT).show();
}
}
private void initCamera(){
camera = Camera.open(0);
surfaceViewWidth = surfaceview.getWidth();
surfaceViewHeight = surfaceview.getHeight();
Log.e(TAG, "surfaceCreated: " + surfaceview.getWidth() + " " + surfaceview.getHeight() );
if (camera != null) {
try {
camera.setPreviewCallback(this);
Camera.Parameters parameters = camera.getParameters();
//需要設(shè)置大小,否則在聚焦后就才色調(diào)出現(xiàn)縮小
parameters.setPreviewSize(height,width);
camera.setParameters(parameters);
camera.setDisplayOrientation(90);
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void surfaceCreated(@NonNull SurfaceHolder surfaceHolder) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.CAMERA},1);
}else {
initCamera();
}
}
@Override
public void surfaceChanged(@NonNull SurfaceHolder surfaceHolder, int i, int i1, int i2) {
}
@Override
public void surfaceDestroyed(@NonNull SurfaceHolder surfaceHolder) {
if (camera != null){
camera.setPreviewCallback(null);
camera.stopPreview();
camera.release();
camera = null;
}
}
@Override
public void onPreviewFrame(byte[] bytes, Camera camera) {
}
class AutoFocusCallBackClass implements Camera.AutoFocusCallback{
@Override
public void onAutoFocus(boolean b, Camera camera) {
Log.e(TAG, "onAutoFocus: " + b);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (camera != null){
camera.setPreviewCallback(null);
camera.stopPreview();
camera.release();
camera = null;
}
}
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android監(jiān)聽Home鍵和Back鍵的區(qū)別介紹
這篇文章主要介紹了Android監(jiān)聽Home鍵和Back鍵的區(qū)別介紹,本文還同時(shí)給出了Home鍵監(jiān)聽的實(shí)現(xiàn)代碼,需要的朋友可以參考下2015-06-06
創(chuàng)建子線程對(duì)Android進(jìn)行網(wǎng)絡(luò)訪問
這篇文章介紹了Android中創(chuàng)建子線程進(jìn)行網(wǎng)絡(luò)訪問的方法,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考2021-11-11
Android實(shí)現(xiàn)簡易計(jì)步器功能隔天步數(shù)清零查看歷史運(yùn)動(dòng)紀(jì)錄
這篇文章主要介紹了Android實(shí)現(xiàn)簡易計(jì)步器功能隔天步數(shù)清零查看歷史運(yùn)動(dòng)紀(jì)錄,需要的朋友可以參考下2017-06-06
Android App數(shù)據(jù)格式Json解析方法和常見問題
JSON數(shù)據(jù)格式,在Android中被廣泛運(yùn)用于客戶端和網(wǎng)絡(luò)(或者說服務(wù)器)通信,非常有必要系統(tǒng)的了解學(xué)習(xí)。恰逢本人最近對(duì)json做了一個(gè)簡單的學(xué)習(xí),特此總結(jié)一下,以饗各位2014-03-03
Android實(shí)現(xiàn)分享長圖并且添加全圖水印
這篇文章主要介紹了Android實(shí)現(xiàn)分享長圖并且添加全圖水印的相關(guān)資料,需要的朋友可以參考下2017-03-03
在Android中查看當(dāng)前Activity是否銷毀的操作
這篇文章主要介紹了在Android中查看當(dāng)前Activity是否銷毀的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-03-03
android 仿QQ動(dòng)態(tài)背景、視頻背景的示例代碼
本篇文章主要介紹了android 仿QQ動(dòng)態(tài)背景、視頻背景的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-03-03
android獲取手機(jī)IMSI碼判斷手機(jī)運(yùn)營商代碼實(shí)例
這篇文章主要介紹了android獲取手機(jī)IMSI碼判斷手機(jī)運(yùn)營商代碼實(shí)例,大家參考使用2013-11-11
Android中使用ListView實(shí)現(xiàn)漂亮的表格效果
這篇文章主要介紹了Android中使用ListView實(shí)現(xiàn)漂亮的表格效果,本文用詳細(xì)的代碼實(shí)例創(chuàng)建了一個(gè)股票行情表格,需要的朋友可以參考下2014-10-10
Android Studio 4.0新特性及升級(jí)異常問題的解決方案
這篇文章主要介紹了Android Studio 4.0新特性及升級(jí)異常的相關(guān)問題,本文給大家分享解決方案,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-06-06

