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
- android 相机圆形,矩形拍照预览
- Android--相机预览及拍照临时文件/SurfaceView
- Android--相机预览及拍照临时文件/SurfaceView
- Android--相机预览及拍照临时文件/SurfaceView
- Android相机(摄像头)圆形预览窗口,圆形SurfaceView
- Android调用系统相机拍照后不进入预览确认
- Android自定义相机实现拍照、预览、显示、上传
- 适配android 7的自定义相机的预览及拍照
- 【Android】Android相机拍照
- android相机拍照
- android相机拍照源码
- Android中相机拍照
- Android相机拍照,储存
- android相机camera拍照
- android打开相机拍照
- android自定义相机拍照
- Android相机预览方向
- Android相机开发(一)之预览拍照查看图片基本功能的实现
- windows7下安装php的imagick和imagemagick扩展教程
- iOS APP 如何做才安全
- netstat
- 上拉加载下拉刷新
- 解决spring整合hibernate后不能用getCurrentSession()的问题
- android 相机圆形,矩形拍照预览
- 每天一个linux命令(2):cd命令
- 线程池(7)——基本使用(下)
- ROS_OpenCV+PCL程序
- poj1384
- MFC入门(二)-- 提取输入框的字符串(定时关机的小程序)
- 封锁阳光大学(染色)
- ajax中的跨域请求及原理
- 关于版本更新