解决camera预览时出现拉伸问题

第一步配置:

根目录下的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  获得

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qq_41620230

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值