Android 使用Camera 打开预览Demo

camera.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">
    <TextureView
        android:id="@+id/textureView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    <Button
        android:id="@+id/btnStop"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="0.8dp"
        android:text="stop preview"
        android:layout_alignParentBottom="true"
        android:layout_alignParentEnd="true"/>
    <Button
        android:id="@+id/btnStart"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="0.8dp"
        android:text="start preview"
        android:layout_alignParentBottom="true"
        android:layout_toStartOf="@id/btnStop"/>
</RelativeLayout>

CameraTest.java

package com.neostra.closereminder;

import android.app.Activity;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.os.Bundle;
import android.util.Log;
import android.view.TextureView;
import android.view.View;

import java.io.IOException;
import java.util.List;

public class CameraTest extends Activity implements TextureView.SurfaceTextureListener {

    private static final String TAG = "CameraTest";

    private Camera camera;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.camera);

        ((TextureView) findViewById(R.id.textureView)).setSurfaceTextureListener(this);

        findViewById(R.id.btnStart).setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                camera.startPreview();
            }
        });

        findViewById(R.id.btnStop).setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                camera.stopPreview();
            }
        });
    }

    private Camera createCamera(int width, int height) {
        Camera camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);


        Camera.Parameters parameters = camera.getParameters();
        Camera.CameraInfo camInfo = new Camera.CameraInfo();
        Camera.getCameraInfo(Camera.CameraInfo.CAMERA_FACING_BACK, camInfo);
        Camera.Size bestSize = getOptimalPreviewSize(parameters.getSupportedPreviewSizes(), width, height);
        Log.i(TAG, "best preview size: " + bestSize.width + ", " + bestSize.height);
        parameters.setPreviewSize(bestSize.width, bestSize.height);
        Camera.Size bestPictureSize = getOptimalPictureSize(parameters.getSupportedPictureSizes(), width, height);
        Log.i(TAG, "best picture size: " + bestPictureSize.width + ", " + bestPictureSize.height);
        parameters.setPictureSize(bestPictureSize.width, bestPictureSize.height);
        camera.setParameters(parameters);
        return camera;
    }

    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
        Log.i(TAG, "onSurfaceTextureAvailable: " + width + ", " + height);
        camera = createCamera(width, height);
        camera.setPreviewCallback(new Camera.PreviewCallback() {

            @Override
            public void onPreviewFrame(byte[] data, Camera camera) {
                // Log.i(TAG, "onPreviewFrame: " + data.length);
            }
        });
        try {
            camera.setPreviewTexture(surface);
        } catch (IOException e) {
            e.printStackTrace();
        }
        camera.startPreview();
    }

    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
        camera.setPreviewCallback(null);
        camera.stopPreview();
        camera.lock();
        camera.release();
        return false;
    }

    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
        // NOOP
    }

    @Override
    public void onSurfaceTextureUpdated(SurfaceTexture surface) {
        // NOOP
    }

    // ======================================== 工具方法 ========================================

    //获取相机最佳预览大小、图像大小
    //注意每台手机获取的PreviewSize顺序不一样
    public static Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) {
        final double aspectTolerance = 0.1;
        int width = w;
        int height = h;

        if (height > width) {
            int temp = width;
            width = height;
            height = temp;
        }

        double targetRatio = (double) width / height;
        if (sizes == null) {
            return null;
        }

        if (Math.abs(targetRatio - (double) 4 / 3) < 0.1) {
            targetRatio = (double) 4 / 3;
        } else {
            targetRatio = (double) 16 / 9;
        }

        Camera.Size optimalSize = null;
        double minDiff = Double.MAX_VALUE;

        int targetHeight = h;
        // Try to find an size match aspect ratio and size
        for (Camera.Size size : sizes) {
            double ratio = (double) size.width / size.height;
            if (Math.abs(ratio - targetRatio) > aspectTolerance) {
                continue;
            }
            //获取的最佳分辨率是经过压缩的
            if (Math.abs(size.height - targetHeight) < minDiff && (size.width <= w && size.height <= h)
                    && (optimalSize == null || optimalSize.width < size.width)) {
                optimalSize = size;
            }
        }

        // Cannot find the one match the aspect ratio, ignore the requirement
        if (optimalSize == null) {
            optimalSize = getOptimalSize(sizes, targetHeight);
        }
        return optimalSize;
    }

    public static Camera.Size getOptimalPictureSize(List<Camera.Size> sizes, int w, int h) {
        int minHeight = 1080;
        final double ASPECT_TOLERANCE = 0.2;
        double targetRatio = (double) w / h;
        if (sizes == null)
            return null;

        Camera.Size optimalSize = null;
        double minDiff = Double.MAX_VALUE;

        int targetHeight = h;

        // Try to find an size match aspect ratio and size
        for (Camera.Size size : sizes) {
            double ratio = (double) size.width / size.height;
            if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)
                continue;
            if (minHeight <= size.height && Math.abs(size.height - targetHeight) < minDiff) {
                optimalSize = size;
                minDiff = Math.abs(size.height - targetHeight);
            }
        }

        // Cannot find the one match the aspect ratio, ignore the requirement
        if (optimalSize == null) {
            minDiff = Double.MAX_VALUE;
            for (Camera.Size size : sizes) {
                if (minHeight <= size.height && Math.abs(size.height - targetHeight) < minDiff) {
                    optimalSize = size;
                    minDiff = Math.abs(size.height - targetHeight);
                }
            }
        }
        return optimalSize;
    }

    private static Camera.Size getOptimalSize(List<Camera.Size> sizes, int targetHeight) {
        Camera.Size optimalSize = null;
        double minDiff = Double.MAX_VALUE;
        for (Camera.Size size : sizes) {
            if (Math.abs(size.height - targetHeight) < minDiff) {
                optimalSize = size;
                minDiff = Math.abs(size.height - targetHeight);
            }
        }
        if (optimalSize == null) {
            optimalSize = sizes.get(0);
        }
        return optimalSize;
    }
}

添加Camera权限
AndroidManifest.xml

 <uses-permission android:name="android.permission.CAMERA" />
    <uses-feature android:name="android.hardware.camera.autofocus" />
    <uses-feature android:name="android.hardware.camera"/>
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

最乱纷飞的code

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

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

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

打赏作者

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

抵扣说明:

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

余额充值