照相机预览、拍照以及适配问题的完美解决

本文介绍了在Android开发中解决相机预览、拍照及适配问题的实践,包括使用SurfaceView进行预览,自定义CameraInterface类处理相机操作,优化预览Size以避免模糊或变形,并提供了解决预览变形的布局设置技巧。同时强调了全屏设置和权限管理的重要性。
摘要由CSDN通过智能技术生成

         前段时间在做face++相关的功能,对于照相机也是进行了一番研究,小有收获,很感谢有一些大神已经写了相应的博客,让我在他们的项目上进行完善和优化,修复了一些bug,并对机型适配做了一些处理,目前已经保证了团队里面十多部安卓手机的完美适配,具体项目资源可以在http://download.csdn.net/detail/shan286/9799622这个网址上下载。好的,话不多说,直接上代码。

1、首先是关于照相机的预览功能,这里就要说到SurfaceView这个控件,我在布局最底层放了一个自定义的MySurfaceView,然后在它的上层放一个自定义的TakePhotoView,这个TakePhotoView主要是用于当用户想要在拍照的时候绘制自己想要的图片时,就可以在这个View中实现,这里我是画了一个带橙色框框的图片放在了里面。MySurfaceView的代码如下:

import android.content.Context;
import android.graphics.PixelFormat;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

/**
 * Created by xueli on 2016/11/16.
 * 
 * 1、注意点:surfaceview变得可见时,surface被创建;surfaceview隐藏前,surface被销毁
 * 2、实现过程:继承SurfaceView并实现SurfaceHolder.Callback接口
 * ----> SurfaceView.getHolder()获得SurfaceHolder对象
 * ----> SurfaceHolder.addCallback(callback)添加回调函数
 * ----> SurfaceHolder.lockCanvas()获得Canvas对象并锁定画布
 * ----> Canvas绘画
 * ----> SurfaceHolder.unlockCanvasAndPost(Canvas canvas)结束锁定画图,并提交改变,将图形显示。
 */
public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback {

    private static final String TAG = "MySurfaceView";
    private Context mContext;
    private SurfaceHolder mSurfaceHolder;

    public MySurfaceView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mContext = context;
        mSurfaceHolder = getHolder();
        mSurfaceHolder.setFormat(PixelFormat.TRANSPARENT);//translucent半透明 transparent透明
        mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        mSurfaceHolder.addCallback(this);
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        //在创建时激发,一般在这里调用画图的线程。
        Log.i(TAG, "surfaceCreated...");
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
                               int height) {
        //在surface的大小发生改变时激发
        Log.i(TAG, "surfaceChanged...");
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        //销毁时激发,一般在这里将画图的线程停止、释放。
        Log.i(TAG, "surfaceDestroyed...");
        CameraInterface.getInstance().doStopCamera();
    }

    public SurfaceHolder getSurfaceHolder() {
        // SurfaceHolder当作surface的控制器,用来操纵surface
        return mSurfaceHolder;
    }

}

TakePhotoView的代码如下:

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.util.AttributeSet;
import android.view.View;

import com.sherry.ui.R;
import com.sherry.util.DeviceInfoUtil;

/**
 * Created by xueli on 2016/11/16.
 *
 * 自定义拍照框View
 *
 */
public class TakePhotoView extends View {

    private Context mContext;
    private Paint mPaint;

    public TakePhotoView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.mContext = context;
        mPaint = new Paint();
        mPaint.setAntiAlias(false);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        // 拍照框预览的宽高设置
        Rect frame = new Rect(0, 0, DeviceInfoUtil.getScreenWidth(mContext), DeviceInfoUtil.getScreenHeight(mContext) * 17 / 25);
        
        mPaint.setColor(Color.GRAY);
        Rect faceRect = new Rect();
        faceRect.left = frame.left;
        faceRect.right = frame.right;
        faceRect.top = frame.top;
        faceRect.bottom = frame.bottom;
        canvas.drawBitmap(((BitmapDrawable) (getResources().getDrawable(R.drawable.take_photo_bg))).getBitmap(), null, faceRect, mPaint);
    }
}

2、照相机处理类------CameraInterface

(1)在CameraInterface这个类里面对照相机进行一些处理,包括照相机的开启、预览、拍照、销毁等方法,这里参考博客http://blog.csdn.net/yanzi1225627/article/details/33028041,可以说给我提供了很大的帮助。不过我在它的实现上进行了优化和改进,解决了部分手机的黑屏、拍照或预览变形等问题。因为我这边要求的是拍照之后显示图片在下一个页面进行显示,所以拍照之后不会只是暂停然后继续进行预览,另外要注意的是,我这边使用的是前置摄像头,所以在doOpenCamera()方法中要判断手机摄像头的个数,让它选择开启前置摄像头。具体代码如下:

    /**
     * 打开Camera
     *
     * @param callback
     */
    public void doOpenCamera(CamOpenOverCall
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值