android 自定义Camera控件
2016-01-16 16:09
585 查看
简单实现Camera自定义控件:
效果图:
具体代码解释在代码中有记录,主要代码如下:
先看下布局文件:
activity_camera.xml
CameraActivity.java
下面的CustomCamera.java
最后不要忘了,添加权限:
效果图:
具体代码解释在代码中有记录,主要代码如下:
先看下布局文件:
activity_camera.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="center" tools:context=".MainActivity"> <com.example.vic.myapplication.CustomCamera android:id="@+id/camera" android:layout_width="match_parent" android:layout_height="match_parent"/> <ImageView android:layout_marginBottom="8dp" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@mipmap/iv_takephoto" android:onClick="takePhoto" /> </RelativeLayout>
CameraActivity.java
package com.example.vic.myapplication; import android.os.Bundle; import android.view.MotionEvent; import android.view.View; import com.example.vic.myapplication.base.BaseActivity; /** * Created by Administrator on 2016/1/14. */ public class CameraActivity extends BaseActivity { private CustomCamera customCamera; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setToolBarInfo(true); getToolBar_center().setText("Camera"); setContentLayout(R.layout.activity_camera); customCamera = (CustomCamera) findViewById(R.id.camera); } @Override public boolean onTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { customCamera.autoFocus(false); return true; } return super.onTouchEvent(event); } public void takePhoto(View v) { customCamera.autoFocus(true); } }
下面的CustomCamera.java
package com.example.vic.myapplication; import android.app.Activity; import android.content.Context; import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.ImageFormat; import android.graphics.Matrix; import android.hardware.Camera; import android.os.Environment; import android.text.format.Time; import android.util.AttributeSet; import android.view.Surface; import android.view.SurfaceHolder; import android.view.SurfaceView; import com.example.vic.myapplication.utils.AppLog; import com.example.vic.myapplication.utils.AppToast; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; /** * Created by Administrator on 2016/1/14. */ public class CustomCamera extends SurfaceView implements SurfaceHolder.Callback { private Camera camera; private SurfaceHolder holder; private Context context; private String picUrl; public CustomCamera(Context context, AttributeSet attrs) { super(context, attrs); this.context = context; initHolder(); } private void initHolder() { //实例holder holder = this.getHolder(); //设置屏常 亮 holder.setKeepScreenOn(true); //增加一个回调 holder.addCallback(this); } /** * 判断是否存在摄像头 * @param context * @return */ private boolean existCamera(Context context) { return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA); } /** * 初始化相机 * 0 表示后置camera * Camera.getNumberOfCameras()-1 可调用前置camera */ private void initCamera() { if (camera == null) { // camera = Camera.open(Camera.getNumberOfCameras() - 1);//前置摄像头 camera = Camera.open(); } } private void imagePreview(SurfaceHolder holder) { try { if (camera != null) { //设置预览显示到holder camera.setPreviewDisplay(holder); //系统默认是横向的, 所以要设置方向为顺时针90度 camera.setDisplayOrientation(90); //开始预览 camera.startPreview(); } } catch (IOException e) { e.printStackTrace(); } } private void setParameters() { if (camera != null) { //获取相机的参数设置对象 Camera.Parameters parameters = camera.getParameters(); //设置图片格式 parameters.setPictureFormat(ImageFormat.JPEG); //设置自动闪光灯 parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO); //对parametrs对象进行修改后,重新赋值 camera.setParameters(parameters); } } private void releaseCamera() { if (camera != null) { //取消预览回调 camera.setPreviewCallback(null); //停止预览 camera.stopPreview(); //释放camera camera.release(); //置空 camera = null; } } /** * 自动聚焦 * @param b ture为自动聚焦后,就拍照, false为只自动聚焦 */ public void autoFocus(final boolean b) { if (camera != null) { camera.autoFocus(new Camera.AutoFocusCallback() { @Override public void onAutoFocus(boolean success, Camera camera) { if (success) { if (b) takePicture(); } } }); } } public void takePicture() { if (camera != null) { camera.takePicture(null, null, new Camera.PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { // data就是图片信息 //声明bitmap对象 Bitmap bMap; try { //将数据读到bitmap bMap = BitmapFactory.decodeByteArray(data, 0, data.length); //系统默认返回图片是横向的,下面操作对照片就行旋转90度 Bitmap bMap2; Matrix matrix = new Matrix(); matrix.reset(); matrix.setRotate(90); bMap2 = Bitmap.createBitmap(bMap, 0, 0, bMap.getWidth(), bMap.getHeight(), matrix, true); bMap = bMap2; //照片保存 if (picUrl == null) { picUrl = Environment.getExternalStorageDirectory() + File.separator +pictureName()+".jpg"; } File file = new File(picUrl); if (file.exists()) { file.delete(); } BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file)); bMap.compress(Bitmap.CompressFormat.JPEG, 100, bos);//将图片压缩到流中 bos.flush();//输出 bos.close();//关闭 bMap.recycle(); bMap2.recycle(); //保存后,重新预览 imagePreview(holder); } catch (Exception e) { e.printStackTrace(); } } }); } } @Overrid 4000 e public void surfaceCreated(SurfaceHolder holder) { if (existCamera(context)) { initCamera(); } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { AppLog.Log("surfaceChanged()"); setParameters(); imagePreview(holder); } @Override public void surfaceDestroyed(SurfaceHolder holder) { AppLog.Log("surfaceDestroyed()"); releaseCamera(); } public void setPicUrl(String picUrl) { this.picUrl = picUrl; AppLog.Log("setPicUrl()"); } public String pictureName() { String str = ""; Time t = new Time(); t.setToNow(); // 取得系统时间。 int year = t.year; int month = t.month + 1; int date = t.monthDay; int hour = t.hour; // 0-23 int minute = t.minute; int second = t.second; if (month < 10) str = String.valueOf(year) + "0" + String.valueOf(month); else { str = String.valueOf(year) + String.valueOf(month); } if (date < 10) str = str + "0" + String.valueOf(date + "_"); else { str = str + String.valueOf(date + "_"); } if (hour < 10) str = str + "0" + String.valueOf(hour); else { str = str + String.valueOf(hour); } if (minute < 10) str = str + "0" + String.valueOf(minute); else { str = str + String.valueOf(minute); } if (second < 10) str = str + "0" + String.valueOf(second); else { str = str + String.valueOf(second); } return str; } }
最后不要忘了,添加权限:
<uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-feature android:name="android.hardware.camera" /> <uses-feature android:name="android.hardware.camera.autofocus" />
相关文章推荐
- android四大组件---BroadCastReceiver
- Android 自己定义View (二) 进阶
- Android的startActivity过程
- android 学习好的网址汇总
- Android ScrollView嵌套HorizontalScrollView 滑动问题 ScrollView包括GridView显示问题
- Android动态加载及hook资料汇总
- 解决Android中,禁止ScrollView内的控件改变之后自动滚动
- android(android studio)中使用注解框架butterknife
- android studio preference 在哪
- java自带线程池和队列详细讲解,android中适用
- android 服务
- Android 自定义设置图片模糊度、高斯模糊效果
- Android真机连接本地服务器测试
- android 检测sqlite数据表中字段(列)是否存在
- Android版本升级同时Sqlite数据库的升级及之前数据的保留-转
- 新出炉的Android Studio快捷键
- 表白程序源代码,android
- android studio的里的 content_XXX_xml问题
- 在脚本中, 使用sqlite3检查android程序生成的数据库是否OK
- 【Android源码-AMS】(一)Instrumentation类解析