android 相机圆形,矩形拍照预览

来源:互联网 发布:linux ssh是否安装 编辑:程序博客网 时间:2024/05/18 02:58

首先,相机这块我也不是特别懂,之前也没开发过这块。参考了YanZi大神的文章http://blog.csdn.net/yanzi1225627/article/details/34931759不多说,看下效果图矩形的:

这里写图片描述

拍照后

这里写图片描述

圆形的拍照界面

这里写图片描述

这里写图片描述

package com.example.camera;

import java.io.File;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.graphics.Point;
import android.graphics.Rect;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.ImageButton;

import com.example.camera.CameraInterface.CamOpenOverCallback;

public class CameraActivity extends Activity implements CamOpenOverCallback{
private static final String TAG = “CameraActivity”;

CameraSurfaceView surfaceView = null;ImageButton shutterBtn;MaskView maskView = null;float previewRate = -1f;int DST_CENTER_RECT_WIDTH = 350;//单位是dpint DST_CENTER_RECT_HEIGHT = 350;Point rectPictureSize = null;private String thumbPath = null;@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_camera);    initUI();    initViewParams();

// Intent intent = new Intent(this,CameraActivity.class);
// this.bindService(intent, conn, Context.BIND_AUTO_CREATE);
startCamera();
RegisterReceiever();
}

private void startCamera() {    Thread openThread = new Thread(){        @Override        public void run() {        CameraInterface.getInstance(CameraActivity.this).doOpenCamera(CameraActivity.this);        }    };    openThread.start();}private void initUI() {    surfaceView =(CameraSurfaceView) findViewById(R.id.camera_surfaceview);    shutterBtn = (ImageButton)findViewById(R.id.btn_shutter);    shutterBtn.setOnClickListener(new BtnListener());    maskView = (MaskView)findViewById(R.id.view_mask);}private void initViewParams() {    LayoutParams params = surfaceView.getLayoutParams();    Point p = DisplayUtil.getScreenMetrics(this);    params.width = p.x;    params.height = p.y;    Log.i(TAG, "screenwidth = "+ p.x +"screenheight = "+p.y);    previewRate = DisplayUtil.getScreenRate(this);//默认全屏的比例预览    surfaceView.setLayoutParams(params);    LayoutParams p2 = shutterBtn.getLayoutParams();    p2.width = DisplayUtil.dip2px(this, 80);    p2.height = DisplayUtil.dip2px(this, 80);    shutterBtn.setLayoutParams(p2);}@Overridepublic void cameraHasOpened() {    SurfaceHolder holder = surfaceView.getSurfaceHolder();    CameraInterface.getInstance(CameraActivity.this).doStartPreView(holder, previewRate);    if(maskView != null){        Rect screenCenterRect = createCenterScreenRect(                DisplayUtil.dip2px(this, DST_CENTER_RECT_WIDTH),                DisplayUtil.dip2px(this, DST_CENTER_RECT_HEIGHT));        maskView.setCenterRect(screenCenterRect);    }}private void RegisterReceiever() {    IntentFilter intentFilter = new IntentFilter();    intentFilter.addAction(FileUtil.ACTION_SERVICE);    CameraActivity.this.registerReceiver(reciever, intentFilter);    Log.i(TAG, "RegisterReceiever ======================== ");}

// private ServiceConnection conn = new ServiceConnection() {
//
// @Override
// public void onServiceDisconnected(ComponentName name) {
//
// }
//
// @Override
// public void onServiceConnected(ComponentName name, IBinder service) {
// Log.i(TAG, “服务已经连接。。。=+++++++++++++++++++++++++++++++++++”);
// }
// };

private BroadcastReceiver reciever = new BroadcastReceiver(){    @Override    public void onReceive(Context context, Intent intent) {         String action = intent.getAction();         if(action.equals(FileUtil.ACTION_SERVICE)){             if(intent != null){                 thumbPath= intent.getStringExtra("thumbPath");                 if(thumbPath != null){                     File file = new File(thumbPath);                     Uri uri = Uri.fromFile(file);                     Intent i = new Intent(CameraActivity.this,ShowImageActivity.class);                     i.setData(uri);                     i.putExtra("thumbPath", thumbPath);                     Log.i(TAG, "Uri =============================================================== " + uri.toString());                     startActivity(i);                     finish();                 }             }         }    }};@Overrideprotected void onRestart() {    // TODO Auto-generated method stub    super.onRestart();    startCamera();}@Overrideprotected void onResume() {    // TODO Auto-generated method stub    super.onResume();}@Overrideprotected void onStop() {    super.onStop();};@Overrideprotected void onDestroy() {    super.onDestroy();    unregisterReceiver(reciever);};private class BtnListener implements OnClickListener{    @Override    public void onClick(View v) {        switch(v.getId()){        case R.id.btn_shutter:            if(rectPictureSize == null){                rectPictureSize = createCenterPictureRect(                        DisplayUtil.dip2px(CameraActivity.this, DST_CENTER_RECT_WIDTH),                        DisplayUtil.dip2px(CameraActivity.this, DST_CENTER_RECT_HEIGHT));            }            CameraInterface.getInstance(CameraActivity.this).doTakePicture(rectPictureSize.x,rectPictureSize.y);            break;        }    }}/** * 生成拍照后图片的中间矩形的宽度和高度 * @param w 屏幕上的矩形宽度,单位px * @param h 屏幕上的矩形高度 * @return */private Point createCenterPictureRect(int w, int h){    int wScreen = DisplayUtil.getScreenMetrics(this).x;    int hScreen = DisplayUtil.getScreenMetrics(this).y;    int wSavePicture = CameraInterface.getInstance(CameraActivity.this).doGetPrictureSize().y;//因为图片旋转了,所以宽高换位    int hSavePicture = CameraInterface.getInstance(CameraActivity.this).doGetPrictureSize().x;    float wRate = (float)(wSavePicture) / (float)(wScreen);    float hRate = (float)(hSavePicture) / (float)(hScreen);    float rate = (wRate <= hRate) ? wRate : hRate;//也可以按照最小比率计算    int wRectPicture = (int)(w * wRate);    int hRectPicture = (int)(h * hRate);    return new Point(wRectPicture,hRectPicture);}/** * 生成屏幕中间的矩形 * @param w 目标矩形的宽度,单位px * @param h 目标矩形的高度,单位px * @return */private Rect createCenterScreenRect(int w,int h){    int x1 = DisplayUtil.getScreenMetrics(this).x / 2 - w / 2;    int y1 = DisplayUtil.getScreenMetrics(this).y / 2 - h / 2;    int x2 = x1 + w ;    int y2 = y1 + h;    return new Rect(x1, y1, x2, y2);}

}

当然了需要surfaceView

package com.example.camera;

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

public class CameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
private static final String TAG = “CameraSurfaceView”;
CameraInterface mCameraInterface;
Context mContext;
SurfaceHolder mSurfaceHolder;

public CameraSurfaceView(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);}@Overridepublic void surfaceCreated(SurfaceHolder holder) {    Log.i(TAG, "surfaceCreated");

// CameraInterface.getInstance().doOpenCamera(null);
}

@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width,        int height) {    Log.i(TAG, "surfaceChanged..");    CameraInterface.getInstance(mContext).doStartPreView(mSurfaceHolder, 1.333f);}@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {    Log.i(TAG, "surfaceDestroyed");    CameraInterface.getInstance(mContext).doStopCamera();}public SurfaceHolder getSurfaceHolder(){    return mSurfaceHolder;}

}

最后定义的接口,但后来需要传数据,我就让它继承Service了

package com.example.camera;

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

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.ShutterCallback;
import android.hardware.Camera.Size;
import android.net.Uri;
import android.os.IBinder;
import android.util.Log;
import android.view.SurfaceHolder;

@SuppressWarnings(“deprecation”)
public class CameraInterface extends Service{
private static final String TAG = “CameraInterface”;
private Camera mCamera;
private Camera.Parameters mParams;
private boolean isPreviewing = false ;
private float mPreviewRate = -1f;
private static CameraInterface mCameraInterface;
private Context mContext;

int DST_RECT_WIDTH, DST_RECT_HEIGHT;public interface CamOpenOverCallback{    public void cameraHasOpened();}

// private CameraInterface(){
//
// }

public CameraInterface(Context mContext) {    super();    this.mContext = mContext;}

// public static synchronized CameraInterface getInstance(){
// if(mCameraInterface == null){
// mCameraInterface = new CameraInterface();
// }
// return mCameraInterface;
// }
//chuan Context
public static synchronized CameraInterface getInstance(Context mContext){
if(mCameraInterface == null){
mCameraInterface = new CameraInterface(mContext);
}
return mCameraInterface;
}

/**打开Camera *@param  callback */public void doOpenCamera(CamOpenOverCallback callback){    Log.i(TAG, "Camera open ...");    try {        Thread.sleep(1000);    } catch (InterruptedException e) {        e.printStackTrace();    }    mCamera = Camera.open();    Log.i(TAG, "Camera open over..");    if(callback != null){        callback.cameraHasOpened();    }}/**使用SurfaceView 开启预览 * @param holder * @param previewRate */public void doStartPreView(SurfaceHolder holder , float previewRate){    Log.i(TAG, "doStartPreview");    if(isPreviewing){        mCamera.stopPreview();        return;    }    if(mCamera != null){        try {            mCamera.setPreviewDisplay(holder);        } catch (IOException e) {            e.printStackTrace();        }        initCamera(previewRate);    }}/** * 使用TextureView 预览 Camera * @param previewRate */public void doStartPreview(SurfaceTexture surface , float previewRate){    Log.i(TAG, "doStartPreview ..");    if(isPreviewing){        mCamera.stopPreview();        return;    }    if(mCamera != null){    try {        mCamera.setPreviewTexture(surface);    } catch (IOException e) {        e.printStackTrace();    }    initCamera(previewRate);}

}
/**
* 停止预览,释放Camera
* @param
*/
public void doStopCamera(){
if(mCamera != null){
mCamera.setPreviewCallback(null);
mCamera.stopPreview();
isPreviewing = false;
mPreviewRate = -1f;
mCamera.release();
mCamera = null;
}
}

/** * 拍照 */public void doTakePicture(){    if(isPreviewing && (mCamera != null)){        mCamera.takePicture(mShutterCallback, null, mJpegPictureCallback);    }}public void doTakePicture(int w, int h){    if(isPreviewing && (mCamera != null)){        Log.i(TAG, "矩形拍照尺寸:width =  " + w + "height =" + h);        DST_RECT_WIDTH = w;        DST_RECT_HEIGHT = h;        mCamera.takePicture(mShutterCallback, null, mRectJpegPictureCallback);    }}public Point doGetPrictureSize(){    Size s = mCamera.getParameters().getPictureSize();    return new Point(s.width,s.height);}private void initCamera(float previewRate) {    if(mCamera != null){        mParams = mCamera.getParameters();        mParams.setPictureFormat(PixelFormat.JPEG);//设置拍照后的存储的图片格式        //设置PreviewSize 和 PictureSize        Size pictureSize = CamParaUtil.getInstance().getPropPictureSize(                mParams.getSupportedPictureSizes(), previewRate, 800);        mParams.setPictureSize(pictureSize.width, pictureSize.height);        Size previewSize = CamParaUtil.getInstance().getPropPreviewSize(                mParams.getSupportedPreviewSizes(), previewRate, 800);        mParams.setPreviewSize(previewSize.width, previewSize.height);        mCamera.setDisplayOrientation(90);        List<String> focusModes = mParams.getSupportedFocusModes();        if(focusModes.contains("continuous-video")){            mParams.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);        }        mCamera.setParameters(mParams);        mCamera.startPreview(); // 开启预览        isPreviewing = true ;        mPreviewRate = previewRate;        mParams = mCamera.getParameters();//重新get一次        Log.i(TAG, "最终设置:PreviewSize--With = " + mParams.getPreviewSize().width                + "Height = " + mParams.getPreviewSize().height);        Log.i(TAG, "最终设置:PictureSize--With = " + mParams.getPictureSize().width                + "Height = " + mParams.getPictureSize().height);    }}//为了实现拍照的快门声音及拍照保存照片需要下面三个回调变量ShutterCallback mShutterCallback = new ShutterCallback() {    //快门按下的回调,在这里我们可以设置类似播放咔嚓之类的操作,默认的就是咔嚓    @Override    public void onShutter() {    }};PictureCallback mRawCallback = new PictureCallback() {    //拍摄的未压缩原数据的回调,可以为null    @Override    public void onPictureTaken(byte[] data, Camera camera) {    }};/** * 常规的回调 */PictureCallback mJpegPictureCallback = new PictureCallback() {    //对jpeg图像数据的回调,最重要的一个回调    @Override    public void onPictureTaken(byte[] data, Camera camera) {        Bitmap b = null;        if(data != null){            b = BitmapFactory.decodeByteArray(data, 0, data.length);//data是字节数据,将其解析成类图            mCamera.stopPreview();            isPreviewing = false;        }        //保存图片到sdcard        if(b != null){            //设置FOCUS_MODE_CONTINUOUS_VIDEO 之后,myParam.set("rotation",90);失效            //图片不能旋转,在这里旋转            Bitmap rotaBitmap = ImageUtil.getRotateBitmap(b, 90.0f);            FileUtil.saveBitmap(rotaBitmap);        }        //再次进入预览        mCamera.startPreview();        isPreviewing = true ;    }};/** * 拍摄指定区域的rect */PictureCallback mRectJpegPictureCallback = new PictureCallback() {    //对jpeg 图像数据的回调,最重要的一个回调    @Override    public void onPictureTaken(byte[] data, Camera camera) {        Bitmap b = null;        if(data != null){            b = BitmapFactory.decodeByteArray(data, 0, data.length);//data是字节数据,将其解析成类图            mCamera.stopPreview();            isPreviewing = false;        }        //保存图片到sdcard        if(b != null){            //设置FOCUS_MODE_CONTINUOUS_VIDEO 之后,myParam.set("rotation",90);失效            //图片不能旋转,在这里旋转            Bitmap rotaBitmap = ImageUtil.getRotateBitmap(b, 90.0f);            int x = rotaBitmap.getWidth()/2 - DST_RECT_WIDTH/2;            int y = rotaBitmap.getHeight()/2 - DST_RECT_HEIGHT/2;                           Log.i(TAG, " rotaBitmap.getWidth() = "+  rotaBitmap.getWidth());            Log.i(TAG, "rotaBitmap.getHeight() = " + rotaBitmap.getHeight());            Bitmap rectBitmap = Bitmap.createBitmap(rotaBitmap, x, y, DST_RECT_WIDTH, DST_RECT_HEIGHT);            FileUtil.saveBitmap(rectBitmap);            if(rotaBitmap.isRecycled()){                rotaBitmap.recycle();                rotaBitmap = null;            }            if(rectBitmap.isRecycled()){                 rectBitmap.recycle();                rectBitmap = null;            }            String thumbPath = FileUtil.getJpegName();            File file = new File(thumbPath);            Uri uri = Uri.fromFile(file);            Log.d(TAG, "==============================================================="+thumbPath);            if(thumbPath != null){                Intent intent = new Intent();                intent.putExtra("thumbPath", thumbPath);                intent.setAction(FileUtil.ACTION_SERVICE);                mContext.sendBroadcast(intent);            }        }        //再次进入预览        mCamera.startPreview();        isPreviewing = true;        if(!b.isRecycled()){            b.recycle();            b = null;        }    }};@Overridepublic IBinder onBind(Intent intent) {    return null;}

}

有个问题是这样的,当打开相机进行预览时,如果我们锁屏了,在打开的时候,我们的surfaceView会定格在那里,如果在Activity中去掉onRestart()方法中的启动相机代码,我们程序在退回后台再打开时,会发现surfaceView预览打不开。这地方有些困惑。希望有解决的方法的兄弟告知一声,不胜感激。。。

最后祝大家工作顺心,生活愉快。

下载地址:
矩形 http://download.csdn.net/detail/wu244208909/9612828
圆形 http://download.csdn.net/detail/wu244208909/9612833

1 0
原创粉丝点击