第一步配置:
根目录下的build.gradle
buildscript { ext.kotlin_version = "1.5.21" repositories { google() jcenter() } dependencies { classpath 'com.android.tools.build:gradle:3.5.3' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } }
allprojects { repositories { google() jcenter() } } task clean(type: Delete) { delete rootProject.buildDir }
app目录下的build.gradle
顶部
apply plugin: 'kotlin-android'
库的引入
//相机 implementation files('libs/fotoapparat-release.aar') implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.0' //Android组件异步通信的框架 implementation 'io.reactivex.rxjava2:rxjava:2.1.3' implementation 'io.reactivex.rxjava2:rxandroid:2.0.1' //RxPermissions权限获取 implementation 'com.tbruyelle.rxpermissions2:rxpermissions:0.9.4@aar'
xml布局
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <io.fotoapparat.view.CameraView android:id="@+id/cameraView" android:layout_width="match_parent" android:layout_height="550sp"> <!--Optionally add tap to focus--> <io.fotoapparat.view.FocusView android:id="@+id/focusView" android:layout_width="match_parent" android:layout_height="550sp" /> </io.fotoapparat.view.CameraView> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:gravity="center"> <Button android:id="@+id/takephoto" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="拍照" /> <Button android:id="@+id/btnStart" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@+id/takephoto" android:text="闪光灯" /> </LinearLayout> </RelativeLayout>
主程序:
package com.renhui.rhcamera2; import static io.fotoapparat.result.transformer.ResolutionTransformersKt.scaled; import static io.fotoapparat.selector.FlashSelectorsKt.off; import static io.fotoapparat.selector.FlashSelectorsKt.torch; import java.math.BigDecimal; import android.Manifest; import android.annotation.SuppressLint; import android.graphics.Bitmap; import android.graphics.Matrix; import android.hardware.Camera; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.View; import android.widget.Button; import com.tbruyelle.rxpermissions2.RxPermissions; import io.fotoapparat.Fotoapparat; import io.fotoapparat.capability.Capabilities; import io.fotoapparat.configuration.UpdateConfiguration; import io.fotoapparat.parameter.Resolution; import io.fotoapparat.parameter.Zoom; import io.fotoapparat.result.BitmapPhoto; import io.fotoapparat.result.PhotoResult; import io.fotoapparat.view.CameraView; import io.fotoapparat.view.FocusView; import io.reactivex.functions.Consumer; import kotlin.Unit; import kotlin.jvm.functions.Function1; /** * 本类使用Camera2使用简单相机 */ public class MainActivity2 extends AppCompatActivity { private static final String TAG = "Camera2Test"; CameraView mCameraView; FocusView mFocusView; private Button light; private Button takePhoto2; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.e(TAG, "onCreate!"); setContentView(R.layout.activity_main); intiView(); initEvent(); } private void intiView() { mCameraView = findViewById(R.id.cameraView); mFocusView = findViewById(R.id.focusView); light = (Button) findViewById(R.id.btnStart); takePhoto2 = (Button) findViewById(R.id.takephoto); } private boolean isOpenFlahsLight = false;//是否打开手电筒 private void initEvent() { light.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (isOpenFlahsLight) { if (mFotoapparat != null) { mFotoapparat.updateConfiguration(UpdateConfiguration.builder().flash(off()).build()); } } else { if (mFotoapparat != null) { mFotoapparat.updateConfiguration(UpdateConfiguration.builder().flash(torch()).build()); } } isOpenFlahsLight = !isOpenFlahsLight; } }); takePhoto2.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { initSfvCamera(); } }); } /** * 初始化自定义相机预览界面 */ private void initSfvCamera() { requestPermissions(-1); } private Fotoapparat mFotoapparat; /** * 获取权限 * <p> */ @SuppressLint("CheckResult") public void requestPermissions(final int viewId) { RxPermissions rxPermission = new RxPermissions(this); rxPermission.request( Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE) .subscribe(new Consumer<Boolean>() { @Override public void accept(Boolean isAccess) throws Exception { if (isAccess) { if (viewId == -1) { mFotoapparat = new Fotoapparat(MainActivity2.this, mCameraView, mFocusView); mFotoapparat.start(); adjustViewsVisibility(); //重新初始化手电筒 isOpenFlahsLight = false; } takePhoto(); } } }); } /** * 拍照 */ private void takePhoto() { try { if (mFotoapparat == null) { return; } PhotoResult result = mFotoapparat.takePicture(); result.toBitmap(new Function1<Resolution, Resolution>() { @Override public Resolution invoke(Resolution resolution) { return scaled(0.25f).invoke(resolution); } }) .whenAvailable(new Function1<BitmapPhoto, Unit>() { @Override public Unit invoke(BitmapPhoto bitmapPhoto) { if (bitmapPhoto == null) { return null; } Bitmap bitmap = bitmapPhoto.bitmap; //转向 Matrix matrix = new Matrix(); matrix.setRotate(90); bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, false); //缓存拍照出来的文件 MyFileUtils.compressAndSaveImage(MainActivity2.this, bitmap, 1024 * 2); return null; } }); } catch (Exception e) { } } private void adjustViewsVisibility() { mFotoapparat.getCapabilities() .whenAvailable(new Function1<Capabilities, Unit>() { @Override public Unit invoke(Capabilities capabilities) { if (capabilities == null) { return null; } if (capabilities.getZoom() instanceof Zoom.VariableZoom) { Zoom.VariableZoom zoom = (Zoom.VariableZoom) capabilities.getZoom(); mFocusView.setScaleListener(new Function1<Float, Unit>() { @Override public Unit invoke(Float aFloat) { scaleZoom(aFloat); return null; } }); mFocusView.setPtrListener(new Function1<Integer, Unit>() { @Override public Unit invoke(Integer integer) { return null; } }); } else { mFocusView.setScaleListener(null); mFocusView.setPtrListener(null); } return null; } }); } private float curZoom = 0f; private void scaleZoom(Float scaleFactor) { float plusZoom; if (scaleFactor < 1) { plusZoom = -1 * (1 - scaleFactor); } else { plusZoom = scaleFactor - 1; } float newZoom = new BigDecimal(curZoom).add(new BigDecimal(plusZoom)).floatValue(); if (newZoom < 0 || newZoom > 1) { return; } curZoom = newZoom; mFotoapparat.setZoom(curZoom); } private Camera mCamera;//相机 //聚焦 public void startFocusTimmer() { preHandler.sendEmptyMessageDelayed(2, 2100); } //停止聚焦 public void stopFocusTimer() { preHandler.removeMessages(2); } Handler preHandler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); if (msg.what == 2) { startFocusTimmer(); Log.d("onAutoFocus", "onAutoFocus: " + 1111); //相机聚焦 if (mCamera == null) { return; } Log.d("onAutoFocus", "onAutoFocus: " + 2222); try { // focus = false; mCamera.autoFocus(new Camera.AutoFocusCallback() { @Override public void onAutoFocus(boolean success, Camera camera) { // focus = success; Log.d("onAutoFocus", "onAutoFocus: " + success); if (success) { try { startFocusTimmer(); mCamera.cancelAutoFocus(); } catch (Exception e) { Log.e("exception-->", e.getMessage() + ""); } } } }); } catch (Exception e) { } } } }; //停止聚焦 public void stopTimmer() { preHandler.removeMessages(2); } @Override protected void onResume() { super.onResume(); startFocusTimmer(); } @Override protected void onStart() { super.onStart(); if (mFotoapparat != null) { mFotoapparat.start(); adjustViewsVisibility(); } } @Override protected void onStop() { super.onStop(); stopFocusTimer(); if (mFotoapparat != null) { mFotoapparat.stop(); } } @Override protected void onDestroy() { super.onDestroy(); stopTimmer(); } } 最终效果如下:
相机使用
fotoapparat-release.aar此aar可在https://download.csdn.net/download/qq_41620230/85301683?spm=1001.2014.3001.5503 获得