安卓相机preVIEW并不好看 [英] Android: Camera preview doesn't look nice

查看:111
本文介绍了安卓相机preVIEW并不好看的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经写了相机应用(活动),需要一个图片,而是preVIEW显示摄像机的实时画面看起来并不好看,这是一个有点高,像这样:

下面是code为我的相机preVIEW:

 公共类相机preVIEW延伸SurfaceView实现SurfaceHolder.Callback
    {
        私人SurfaceHolder mHolder;
        私人相机mCamera;
        公共摄像头preVIEW(上下文的背景下,相机摄像头)
        {
            超级(上下文);
            mCamera =摄像头;            mHolder = getHolder();
            mHolder.addCallback(本);
            mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        }
        公共无效surfaceCreated(SurfaceHolder持有人)
        {
            尝试
            {
                mCamera.set previewDisplay(支架);
                mCamera.start preVIEW();
            }
            赶上(IOException异常E)
            {
                Log.d(TAG相机preVIEW失败!:+ e.getMessage());
            }
        }
        公共无效surfaceChanged(SurfaceHolder架,INT男,INT N,INT W)
        {
        }
        公共无效surfaceDestroyed(SurfaceHolder持有人)
        {
        }
    }< XML版本=1.0编码=UTF-8&GT?;
< LinearLayout中的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    机器人:layout_width =FILL_PARENT
    机器人:layout_height =FILL_PARENT
    机器人:方向=垂直>    <的FrameLayout
        机器人:ID =@ + ID / camera_ preVIEW
        机器人:layout_width =WRAP_CONTENT
        机器人:layout_height =0dip
        机器人:layout_weight =0.86/>    <按钮
        机器人:ID =@ + ID / button_capture
        机器人:layout_width =WRAP_CONTENT
        机器人:layout_height =WRAP_CONTENT
        机器人:layout_marginBottom =16DP
        机器人:比重=中心
        安卓的onClick =捕获
        机器人:文字=拍照/>    <按钮
        机器人:ID =@ + ID / button_accept
        机器人:layout_width =115dp
        机器人:layout_height =WRAP_CONTENT
        机器人:文字=接受
        机器人:知名度=水涨船高
        安卓的onClick =接受/>    <按钮
        机器人:ID =@ + ID / button_retake
        机器人:layout_width =107dp
        机器人:layout_height =WRAP_CONTENT
        机器人:文字=重考
        机器人:知名度=水涨船高
        安卓的onClick =夺回/>< / LinearLayout中>


解决方案

 公共类IQCameraView扩展的ViewGroup实现SurfaceHolder.Callback {公共静态最终诠释CAMERA_ERROR = 0;
公共静态最终诠释CAMERA_RESULT = 1;私人最终字符串标记=preVIEW
私人SurfaceView mSurfaceView;
私人SurfaceHolder mHolder;
私人尺寸M previewSize;
私人列表<尺寸和GT; mSupported previewSizes;
私人相机mCamera;私人布尔mCameraActive;私人IQCameraCallback mCallback;/ **
 * @参数mCallback
 类型IQCameraCallback的*
 *为mCallback型空setter函数的@return
 * @since 2012年10月10日
 * /
公共无效setmCallback(IQCameraCallback mCallback){
    this.mCallback = mCallback;
}/ **
 * @参数方面
 类型上下文的*
 *类型布尔函数的@return将检查系统有一个摄像头
 * 或不
 * @since 2012年10月10日
 * /
公共静态布尔checkCameraHardware(上下文的背景下){
    如果(context.getPackageManager()。hasSystemFeature(
            PackageManager.FEATURE_CAMERA)){
        返回true;
    }其他{
        返回false;
    }
}/ **
 * @参数方面
 *构造函数
 * @since 2012年10月16日
 * /
公共IQCameraView(上下文的背景下){
    超级(上下文);    mSurfaceView =新SurfaceView(背景);
    addView(mSurfaceView);
    mHolder = mSurfaceView.getHolder();
    mHolder.addCallback(本);
    mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}/ **
 * @参数摄像头
 类型的相机*
 *为mCamera型空setter函数的@return
 * @since 2012年10月16日
 * /
公共无效setCamera(相机摄像机){
    mCamera =摄像头;
    如果(mCamera!= NULL){
        mSupported previewSizes = mCamera.getParameters()
                .getSupported previewSizes();
        requestLayout();
    }
}/ **
 * @参数
 *类型为null
 *型空函数@返回其将从得到当前帧
 *摄像头
 * @since 2012年10月16日
 * /
公共无效takePicture(){
    如果(空= mCamera和放大器;!&安培; mCameraActive){
        mCamera.takePicture(NULL,NULL,新IQPhotoHandler(的getContext()
                本));
    }
}/ **
 * @参数结果
 String类型*
 *型空函数@返回时,将图像保存为将被称为
 *完整
 * @since 2012年10月16日
 * /
公共无效onImageCapture(最后弦乐结果){
    如果(NULL!= mCallback){
        mCallback.onCameraCallback(CAMERA_RESULT,结果);
    }
    mCamera.start preVIEW();
}/ *
 *(非Javadoc中)
 *
 * @see android.view.View#onMeasure(INT,INT)
 *
 * @since 2012年10月16日
 * /
@覆盖
保护无效onMeasure(INT widthMeasureSpec,诠释heightMeasureSpec){
    //我们故意忽略孩子的测量,因为充当
    //包装到中心相机preVIEW而不是SurfaceView
    //拉伸。
    最终诠释宽度= resolveSize(getSuggestedMinimumWidth()
            widthMeasureSpec);
    最终诠释身高= resolveSize(getSuggestedMinimumHeight()
            heightMeasureSpec);
    setMeasuredDimension(宽度,高度);    如果(mSupported previewSizes!= NULL){
        米previewSize = GET previewSize(mSupported previewSizes,宽,高);
    }
}/ *
 *(非Javadoc中)
 *
 * @see android.view.ViewGroup#onLayout(布尔,INT,INT,INT,INT)
 *
 * @since 2012年10月16日
 * /
@覆盖
保护无效onLayout(布尔变化,诠释L,INT T,INT R,INT B){
    如果(变更&放大器;&放大器; getChildCount()大于0){
        最后查看孩子= getChildAt(0);        最终诠释宽度= R - 1;
        最终诠释身高= B - 吨;        INT previewWidth =宽度;
        INT previewHeight =高度;        //中心父项子SurfaceView。
        如果(宽* previewHeight>高* previewWidth){
            最终诠释scaledChildWidth = previewWidth *高
                    / previewHeight;
            child.layout((宽 - scaledChildWidth)/ 2,0,
                    (宽+ scaledChildWidth)/ 2,高度);
        }其他{
            最终诠释scaledChildHeight = previewHeight *宽
                    / previewWidth;
            child.layout(0,(高度 - scaledChildHeight)/ 2,宽度,
                    (高度+ scaledChildHeight)/ 2);
        }
    }
}/ **
 * @参数
 *类型为null
 *类型为null功能@return这将释放德相机
 * @since 2012年10月16日
 * /
公共无效releaseCamera(){
    如果(空= mCamera和放大器;!&安培; mCameraActive){
        mCamera.stop preVIEW();
        mCamera.release();
        mCamera = NULL;
    }
    mCameraActive = FALSE;
}/ *
 *(非Javadoc中)
 *
 * @see
 * android.view.SurfaceHolder.Callback#surfaceCreated(android.view.SurfaceHolder
 *)
 *
 * @since 2012年10月16日
 * /
公共无效surfaceCreated(SurfaceHolder持有人){
    尝试{
        如果(mCamera!= NULL){
            mCamera.set previewDisplay(支架);
        }
    }赶上(IOException异常五){
        Log.e(TAG,IOException异常造成集previewDisplay(),E);
    }
}/ *
 *(非Javadoc中)
 *
 * @see android.view.SurfaceHolder.Callback#surfaceDestroyed(android.view。
 * SurfaceHolder)
 *
 * @since 2012年10月16日
 * /
公共无效surfaceDestroyed(SurfaceHolder持有人){
    releaseCamera();
}/ *
 *(非Javadoc中)
 *
 * @see
 * android.view.SurfaceHolder.Callback#surfaceChanged(android.view.SurfaceHolder
 *,INT,INT,INT)
 *
 * @since 2012年10月16日
 * /
公共无效surfaceChanged(SurfaceHolder架,INT格式,诠释W,INT高){
    Camera.Parameters参数= mCamera.getParameters();
    parameters.set previewSize(M previewSize.width,男previewSize.height);
    parameters.setPictureSize(M previewSize.width,男previewSize.height);
    parameters.setPictureFormat(PixelFormat.JPEG);
    mCamera.setDisplayOrientation(90);
    requestLayout();
    尝试{
        mCamera.setParameters(参数);
    }赶上(例外五){
        System.out.print(HIH);
    }
    mCamera.start preVIEW();
    mCameraActive =真;
}/ **
 * @参数规格
 类型列表*
 * @参数W¯¯
 类型为int *
 * @参数^ h
 类型为int *
 * @返回类型大小功能optionalSize将找到确切大小
 *需要德摄像机视图
 * @since 2012年10月16日
 * /
私人尺寸的get previewSize(列表<尺寸和GT;的大小,INT W,INT高){
    最终双ASPECT_TOLERANCE = 0.1;
    双targetRatio =(双)W / H;
    如果(大小== NULL)
        返回null;
    大小optimalSize = NULL;
    双minDiff = Double.MAX_VALUE;
    INT targetHeight = H;
    对于(尺寸大小:大小){
        双率=(双)size.width / size.height;
        如果(Math.abs(比 - targetRatio)GT; ASPECT_TOLERANCE)
            继续;
        如果(Math.abs(size.height - targetHeight)LT; minDiff){
            optimalSize =大小;
            minDiff = Math.abs(size.height - targetHeight);
        }
    }    //找不到一个长宽比匹配,忽略此要求
    如果(optimalSize == NULL){
        minDiff = Double.MAX_VALUE;
        对于(尺寸大小:大小){
            如果(Math.abs(size.height - targetHeight)LT; minDiff){
                optimalSize =大小;
                minDiff = Math.abs(size.height - targetHeight);
            }
        }
    }    返回optimalSize;
}/ **
 * @author rajeshcp
 * @since 2012年10月16日
 * /
公共静态界面IQCameraCallback {
    公共无效onCameraCallback(最终int型的,最终目标参数);
}
}

试试这个code已用于项目,希望这将有助于

I've written a camera app (activity) that takes a picture, but the preview that shows the live picture of camera doesn't look nice, it's a bit tall, like this :

Here is the code for my camera preview :

    public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback
    {
        private SurfaceHolder mHolder ;
        private Camera mCamera; 
        public CameraPreview(Context context , Camera camera)
        {
            super(context) ;
            mCamera = camera ;

            mHolder = getHolder();
            mHolder.addCallback(this);
            mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        }
        public void surfaceCreated(SurfaceHolder holder)
        {
            try
            {
                mCamera.setPreviewDisplay(holder);
                mCamera.startPreview();
            }
            catch(IOException e)
            {
                Log.d(TAG,"Camera Preview Failed!: "+e.getMessage());
            }
        }
        public void surfaceChanged(SurfaceHolder holder , int m , int n , int w)
        {   
        }
        public void surfaceDestroyed(SurfaceHolder holder)
        {           
        }
    }



<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <FrameLayout
        android:id="@+id/camera_preview"
        android:layout_width="wrap_content"
        android:layout_height="0dip"
        android:layout_weight="0.86" />

    <Button
        android:id="@+id/button_capture"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="16dp"
        android:gravity="center"
        android:onClick="capture"
        android:text="Capture" />

    <Button
        android:id="@+id/button_accept"
        android:layout_width="115dp"
        android:layout_height="wrap_content"
        android:text="Accept"
        android:visibility="gone"
        android:onClick = "accept" />

    <Button
        android:id="@+id/button_retake"
        android:layout_width="107dp"
        android:layout_height="wrap_content"
        android:text="Retake" 
        android:visibility="gone"
        android:onClick = "retake"/>

</LinearLayout>

解决方案

public class IQCameraView extends ViewGroup implements SurfaceHolder.Callback {

public static final int CAMERA_ERROR = 0;
public static final int CAMERA_RESULT = 1;

private final String TAG = "Preview";
private SurfaceView mSurfaceView;
private SurfaceHolder mHolder;
private Size mPreviewSize;
private List<Size> mSupportedPreviewSizes;
private Camera mCamera;

private boolean mCameraActive;

private IQCameraCallback mCallback;

/**
 * @param mCallback
 *            of type IQCameraCallback
 * @return of type null setter function for mCallback
 * @since 10 Oct 2012
 */
public void setmCallback(IQCameraCallback mCallback) {
    this.mCallback = mCallback;
}

/**
 * @param context
 *            of type Context
 * @return of type boolean function which will check the system has a camera
 *         or not
 * @since 10 Oct 2012
 */
public static boolean checkCameraHardware(Context context) {
    if (context.getPackageManager().hasSystemFeature(
            PackageManager.FEATURE_CAMERA)) {
        return true;
    } else {
        return false;
    }
}

/**
 * @param context
 *            Constructor function
 * @since 16 Oct 2012
 */
public IQCameraView(Context context) {
    super(context);

    mSurfaceView = new SurfaceView(context);
    addView(mSurfaceView);
    mHolder = mSurfaceView.getHolder();
    mHolder.addCallback(this);
    mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}

/**
 * @param camera
 *            of type Camera
 * @return of type null setter function for mCamera
 * @since 16 Oct 2012
 */
public void setCamera(Camera camera) {
    mCamera = camera;
    if (mCamera != null) {
        mSupportedPreviewSizes = mCamera.getParameters()
                .getSupportedPreviewSizes();
        requestLayout();
    }
}

/**
 * @param of
 *            type null
 * @return of type null function which will get the current frame from the
 *         camera
 * @since 16 Oct 2012
 */
public void takePicture() {
    if (null != mCamera && mCameraActive) {
        mCamera.takePicture(null, null, new IQPhotoHandler(getContext(),
                this));
    }
}

/**
 * @param result
 *            of type String
 * @return of type null function which will be called when the image save is
 *         complete
 * @since 16 Oct 2012
 */
public void onImageCapture(final String result) {
    if (null != mCallback) {
        mCallback.onCameraCallback(CAMERA_RESULT, result);
    }
    mCamera.startPreview();
}

/*
 * (non-Javadoc)
 * 
 * @see android.view.View#onMeasure(int, int)
 * 
 * @since 16 Oct 2012
 */
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    // We purposely disregard child measurements because act as a
    // Wrapper to a SurfaceView that centers the camera preview instead of
    // stretching it.
    final int width = resolveSize(getSuggestedMinimumWidth(),
            widthMeasureSpec);
    final int height = resolveSize(getSuggestedMinimumHeight(),
            heightMeasureSpec);
    setMeasuredDimension(width, height);

    if (mSupportedPreviewSizes != null) {
        mPreviewSize = getPreviewSize(mSupportedPreviewSizes, width, height);
    }
}

/*
 * (non-Javadoc)
 * 
 * @see android.view.ViewGroup#onLayout(boolean, int, int, int, int)
 * 
 * @since 16 Oct 2012
 */
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    if (changed && getChildCount() > 0) {
        final View child = getChildAt(0);

        final int width = r - l;
        final int height = b - t;

        int previewWidth = width;
        int previewHeight = height;

        // Center the child SurfaceView within the parent.
        if (width * previewHeight > height * previewWidth) {
            final int scaledChildWidth = previewWidth * height
                    / previewHeight;
            child.layout((width - scaledChildWidth) / 2, 0,
                    (width + scaledChildWidth) / 2, height);
        } else {
            final int scaledChildHeight = previewHeight * width
                    / previewWidth;
            child.layout(0, (height - scaledChildHeight) / 2, width,
                    (height + scaledChildHeight) / 2);
        }
    }
}

/**
 * @param of
 *            type null
 * @return of type null function which will release teh camera
 * @since 16 Oct 2012
 */
public void releaseCamera() {
    if (null != mCamera && mCameraActive) {
        mCamera.stopPreview();
        mCamera.release();
        mCamera = null;
    }
    mCameraActive = false;
}

/*
 * (non-Javadoc)
 * 
 * @see
 * android.view.SurfaceHolder.Callback#surfaceCreated(android.view.SurfaceHolder
 * )
 * 
 * @since 16 Oct 2012
 */
public void surfaceCreated(SurfaceHolder holder) {
    try {
        if (mCamera != null) {
            mCamera.setPreviewDisplay(holder);
        }
    } catch (IOException e) {
        Log.e(TAG, "IOException caused by setPreviewDisplay()", e);
    }
}

/*
 * (non-Javadoc)
 * 
 * @see android.view.SurfaceHolder.Callback#surfaceDestroyed(android.view.
 * SurfaceHolder)
 * 
 * @since 16 Oct 2012
 */
public void surfaceDestroyed(SurfaceHolder holder) {
    releaseCamera();
}

/*
 * (non-Javadoc)
 * 
 * @see
 * android.view.SurfaceHolder.Callback#surfaceChanged(android.view.SurfaceHolder
 * , int, int, int)
 * 
 * @since 16 Oct 2012
 */
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
    Camera.Parameters parameters = mCamera.getParameters();
    parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
    parameters.setPictureSize(mPreviewSize.width, mPreviewSize.height);
    parameters.setPictureFormat(PixelFormat.JPEG);
    mCamera.setDisplayOrientation(90);
    requestLayout();
    try {
        mCamera.setParameters(parameters);
    } catch (Exception e) {
        System.out.print("hih");
    }
    mCamera.startPreview();
    mCameraActive = true;
}

/**
 * @param sizes
 *            of type List
 * @param w
 *            of type int
 * @param h
 *            of type int
 * @return optionalSize of type Size function which will find the exact size
 *         required for teh camera view
 * @since 16 Oct 2012
 */
private Size getPreviewSize(List<Size> sizes, int w, int h) {
    final double ASPECT_TOLERANCE = 0.1;
    double targetRatio = (double) w / h;
    if (sizes == null)
        return null;
    Size optimalSize = null;
    double minDiff = Double.MAX_VALUE;
    int targetHeight = h;
    for (Size size : sizes) {
        double ratio = (double) size.width / size.height;
        if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)
            continue;
        if (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 (Size size : sizes) {
            if (Math.abs(size.height - targetHeight) < minDiff) {
                optimalSize = size;
                minDiff = Math.abs(size.height - targetHeight);
            }
        }
    }

    return optimalSize;
}

/**
 * @author rajeshcp
 * @since 16 Oct 2012
 */
public static interface IQCameraCallback {
    public void onCameraCallback(final int type, final Object param);
}
}

Try this code have used for a project, hope this will help

这篇关于安卓相机preVIEW并不好看的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆