自己写的照相机预览(TextureView)

转载请注明出处:http://blog.csdn.net/ning_gg/article/details/54134918
需要SurfaceView的在这里http://blog.csdn.net/ning_gg/article/details/54090446
使用Textureview的话需要确保使用系统是4.0以后并且在Mainfest中开启调用该Activity的硬件

android:hardwareAccelerated="true"

还是照旧贴上代码 为了简单起见我屏蔽掉了其他功能,精简出了预览版本。


import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.TextureView;

import com.imapedia.ykdemo.utils.L;

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

/**
 * Created by ning_gg on 2017/1/6.
 */
public class CameraTextureView extends TextureView implements TextureView.SurfaceTextureListener{
    private String TAG=CameraTextureView.class.getSimpleName();
    private Context mContext;
    private Camera mCamera;
    private int screenHeight;//屏幕的高度
    private int screenWidth;//屏幕的宽度

    /***
     * 是否支持自动对焦
     */
    private boolean isSupportAutoFocus;
    public static Camera.Size pictureSize;
    private Camera.Size previewSize;
    public CameraTextureView(Context context,AttributeSet attrs) {
        super(context,attrs);
        init(context);
        this.setSurfaceTextureListener(this);
    }

    private void init(Context context) {
        mContext = context;

        DisplayMetrics dm = getResources().getDisplayMetrics();
        screenWidth = dm.widthPixels;
        screenHeight = dm.heightPixels;
        isSupportAutoFocus = context.getPackageManager().hasSystemFeature(
                PackageManager.FEATURE_CAMERA_AUTOFOCUS);
    }

    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i1) {
        L.e(TAG,"onSurfaceTextureAvailable");
        try {
            mCamera = Camera.open();
            if (mCamera == null) {
                return;
            }
            mCamera.setDisplayOrientation(90);
            // 设置holder主要是用于surfaceView的图片的实时预览,以及获取图片等功能,可以理解为控制camera的操作..

            mCamera.setPreviewTexture(surfaceTexture);
            setCameraParms();
           //mCamera.setPreviewCallback(this);
            mCamera.startPreview();
            mCamera.cancelAutoFocus();
            requestLayout();

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i1) {
        L.e(TAG,"onSurfaceTextureSizeChanged");
    }

    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
        L.e(TAG,"onSurfaceTextureDestroyed");
        if (mCamera != null) {
            mCamera.setPreviewCallback(null);
            mCamera.stopPreview();
            mCamera.release();
            mCamera = null;
        }
        return true;
    }

    @Override
    public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
        L.e(TAG,"onSurfaceTextureUpdated");
    }
    private void setCameraParms() {
        Camera.Parameters myParam = mCamera.getParameters();
        List<String> flashModes = myParam.getSupportedFlashModes();
        String flashMode = myParam.getFlashMode();
        // Check if camera flash exists
        if (flashModes == null) {
            return;
        }
        if (!Camera.Parameters.FLASH_MODE_OFF.equals(flashMode)) {
            // Turn off the flash
            if (flashModes.contains(Camera.Parameters.FLASH_MODE_OFF)) {
                myParam.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
            } else {
            }
        }

        float percent = calcPreviewPercent();
        List<Camera.Size> supportedPreviewSizes = myParam.getSupportedPreviewSizes();
        previewSize = getPreviewMaxSize(supportedPreviewSizes, percent);
        L.e(TAG, "预览尺寸w===" + previewSize.width + ",h==="
                + previewSize.height);
        // 获取摄像头支持的各种分辨率
        List<Camera.Size> supportedPictureSizes = myParam.getSupportedPictureSizes();
        pictureSize = findSizeFromList(supportedPictureSizes, previewSize);
        if (pictureSize == null) {
            pictureSize = getPictureMaxSize(supportedPictureSizes, previewSize);
        }
        L.e(TAG, "照片尺寸w===" + pictureSize.width + ",h==="
                + pictureSize.height);
        // 设置照片分辨率,注意要在摄像头支持的范围内选择
        myParam.setPictureSize(pictureSize.width, pictureSize.height);
        // 设置预浏尺寸,注意要在摄像头支持的范围内选择
        myParam.setPreviewSize(previewSize.width, previewSize.height);
        myParam.setJpegQuality(70);

        mCamera.setParameters(myParam);
    }

    private float calcPreviewPercent() {
        float d = screenHeight;
        return d / screenWidth;
    }

    private Camera.Size findSizeFromList(List<Camera.Size> supportedPictureSizes, Camera.Size size) {
        Camera.Size s = null;
        if (supportedPictureSizes != null && !supportedPictureSizes.isEmpty()) {
            for (Camera.Size su : supportedPictureSizes) {
                if (size.width == su.width && size.height == su.height) {
                    s = su;
                    break;
                }
            }
        }
        return s;
    }

    // 根据摄像头的获取与屏幕分辨率最为接近的一个分辨率
    private Camera.Size getPictureMaxSize(List<Camera.Size> l, Camera.Size size) {
        Camera.Size s = null;
        for (int i = 0; i < l.size(); i++) {
            if (l.get(i).width >= size.width && l.get(i).height >= size.width
                    && l.get(i).height != l.get(i).width) {
                if (s == null) {
                    s = l.get(i);
                } else {
                    if (s.height * s.width > l.get(i).width * l.get(i).height) {
                        s = l.get(i);
                    }
                }
            }
        }
        return s;
    }

    // 获取预览的最大分辨率
    private Camera.Size getPreviewMaxSize(List<Camera.Size> l, float j) {
        int idx_best = 0;
        int best_width = 0;
        float best_diff = 100.0f;
        for (int i = 0; i < l.size(); i++) {
            int w = l.get(i).width;
            int h = l.get(i).height;
            if (w * h < screenHeight * screenWidth)
                continue;
            float previewPercent = (float) w / h;
            float diff = Math.abs(previewPercent - j);
            if (diff < best_diff) {
                idx_best = i;
                best_diff = diff;
                best_width = w;
            } else if (diff == best_diff && w > best_width) {
                idx_best = i;
                best_diff = diff;
                best_width = w;
            }
        }
        return l.get(idx_best);
    }
}

Camera有一组预览尺寸,也有一组录像尺寸,还有一组照片尺寸,有人说的录像时尺寸会变形那是因为预览跟录像不搭配的问题导致的,我也做了这个修改,最起码我自己的多个测试手机没有这种变形的问题了。过几天再贴这个录像的吧。

转载请注明出处:http://blog.csdn.net/ning_gg/article/details/54134918

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值