安卓高级8 SurfaceView案例二 自定义相机
效果:(由于不好录屏所以文字描述)
定一个SurfaceView 下方有几个按钮,点击确定可以拍照保存取消.
并且SurfaceView实时显示相机内容
package qianfeng.com.customcamera;
import android.hardware.Camera;
import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback {
private SurfaceView surfaceView;
private SurfaceHolder holder;
private Camera camera;
private byte[] bitmap_byte;
private int flag = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
surfaceView = (SurfaceView) findViewById(R.id.camera_sv);
holder = surfaceView.getHolder();
//设置 Holder 的类型 表示内容 表示内容为空由其他提供
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
holder.addCallback(this);
// 实例化Camera 参数表示 0: 后置摄像头 1:前置摄像头
camera = Camera.open(flag);
// 按照顺时针方向旋转90度
camera.setDisplayOrientation(90);
// 获取一共有多少个摄像头
// Camera.getNumberOfCameras();
}
public void onClick(View view) {
switch (view.getId()) {
case R.id.take_bt:
/*
参数1: 捕捉画面回调
参数2:原声图片回调
参数3: 处理过后的图片回调
*/
camera.takePicture(null, null, new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
//停止预览
camera.stopPreview();
// 记录图片数据
bitmap_byte = data;
}
});
break;
case R.id.cancel_bt:
//取消
bitmap_byte = null;
// 开启预览
camera.startPreview();
break;
case R.id.save_bt:
// 保存
saveToSd();
break;
case R.id.change_bt:
// 切换前后摄像头
//先释放
camera.stopPreview();
camera.release();
camera = null;
// 切换摄像头标记 与当前的标记相反即可
if (flag == 1)
flag = 0;
else if (flag == 0)
flag = 1;
// 重新开启相机
camera = Camera.open(flag);
camera.setDisplayOrientation(90);
try {
camera.setPreviewDisplay(holder);
camera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
break;
}
}
// 保存图片到SD卡
private void saveToSd() {
String filPath = null;
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
filPath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "xixi.png";
}
try {
FileOutputStream out = new FileOutputStream(filPath);
out.write(bitmap_byte, 0, bitmap_byte.length);
out.flush();
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
if (camera != null) {
try {
// 提供预览画面
camera.setPreviewDisplay(holder);
// 开启预览
camera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (camera != null) {
// 销毁的时候停止预览
camera.stopPreview();
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
tools:context="qianfeng.com.customcamera.MainActivity">
<SurfaceView
android:id="@+id/camera_sv"
android:layout_width="match_parent"
android:layout_height="400dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/take_bt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onClick"
android:text="拍照" />
<Button
android:id="@+id/cancel_bt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onClick"
android:text="取消" />
<Button
android:id="@+id/save_bt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onClick"
android:text="保存" />
<Button
android:id="@+id/change_bt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onClick"
android:text="切换" />
</LinearLayout>
</LinearLayout>
安卓高级8 SurfaceView案例二 自定义相机的更多相关文章
- 安卓高级8 SurfaceView案例三 结合mediaplay播放视频
我们知道mediaplay无法直接播放视频所以我们结合Surface package qianfeng.com.mediaplayerdemo; import android.media.MediaP ...
- 安卓高级8 SurfaceView (1)
文章转载:http://www.cnblogs.com/xuling/archive/2011/06/06/android.html 首先我们先来看下官方API对SurfaceView的介绍 Surf ...
- Android Multimedia框架总结(十四)Camera框架初识及自定义相机案例
转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52738492 前言:国庆节告一段 ...
- python第十四课--排序及自定义函数之自定义函数(案例二)
案例二: python中定义有/无返回值的函数,演示python没有函数重载这一说 需求:自定义函数:计算两个整数的和值两个原则:1).有没形参有,两个 2).有没返回值可有可无 def my_sum ...
- python第十四课--排序及自定义函数之案例二:冒泡排序
案例二:冒泡排序 lt1=[45,12,56,-32,-3,44,75,-22,100] print('排序前:'+str(lt1)) 自定义函数:实现冒泡排序(升序)原则:1).有没有形参?有,接受 ...
- 第1节 flume:15、flume案例二,通过自定义拦截器实现数据的脱敏
1.7.flume案例二 案例需求: 在数据采集之后,通过flume的拦截器,实现不需要的数据过滤掉,并将指定的第一个字段进行加密,加密之后再往hdfs上面保存 原始数据与处理之后的数据对比 图一 ...
- Android相机使用(系统相机、自定义相机、大图片处理)
本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显示出来,该例子也会涉及到Android加载大图片时候的处理(避免OOM),还有简要提一下有些人Surf ...
- Android调用系统相机以及自定义相机
0.综述 自定义相机,此处展示简单的相机功能,官方文档中还有相应关于视频拍摄的内容,此处不提 1.添加权限 <!--相机权限,数据存储--> <uses-permission and ...
- Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例 本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显示出来,该例子也会涉及到Android加载大图片时候的处理 ...
随机推荐
- Tensorflow计算模型 —— 计算图
转载自:http://blog.csdn.net/john_xyz/article/details/69053626 Tensorflow是一个通过计算图的形式来表述计算的编程系统,计算图也叫数据流图 ...
- TCP/IP学习笔记:TCP传输控制协议(一)
1 TCP的服务 尽管TCP和UDP都使用相同的网络层(IP),TCP却向用户提供一种面向连接的,可靠地字节流服务.两个使用TCP的应用,在彼此交换数据之前必须先建立一个TCP连接,在一个TCP连接中 ...
- Git的本地仓库与GitHub的远程仓库
gitHub是一个面向开源及私有软件项目的托管平台,因为只支持git 作为唯一的版本库格式进行托管,故名gitHub.GitHub 是目前为止最大的开源 Git 托管服务,并且还是少数同时提供公共代码 ...
- LeetCode Binary Search Summary 二分搜索法小结
二分查找法作为一种常见的查找方法,将原本是线性时间提升到了对数时间范围,大大缩短了搜索时间,具有很大的应用场景,而在LeetCode中,要运用二分搜索法来解的题目也有很多,但是实际上二分查找法的查找目 ...
- MySQL InnoDB 索引原理
本文由 网易云发布. 作者:范鹏程,网易考拉海购 InnoDB是 MySQL最常用的存储引擎,了解InnoDB存储引擎的索引对于日常工作有很大的益处,索引的存在便是为了加速数据库行记录的检索.以下是 ...
- django 表单过滤与查询
7.1 表的查询 查询 Person.objects.all() Person.objects.all()[:10] 切片操作,获取10个人,不支持负索引,切片可以节约内存 Person.object ...
- [LOJ 6270]数据结构板子题
Description 有n个区间,第i个区间是[li,ri],它的长度是ri−li. 有q个询问,每个询问给定L,R,K,询问被[L,R]包含的且长度不小于K的区间数量. 你想,像这种板子题,你随手 ...
- sdut 2878 圆圈
[ 题目描述]现在有一个圆圈, 顺时针标号分别从 0 到 n-1, 每次等概率顺时针走一步或者逆时针走一步,即如果你在 i 号点,你有 1/2 概率走到((i-1)mod n)号点,1/2 概率走到( ...
- 【模板】KMP字符串匹配
题目描述 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置. 为了减少骗分的情况,接下来还要输出子串的前缀数组next. (如果你不知道这是什么意思也不要问,去百度 ...
- 素数密度_NOI导刊2011提高(04)
题目描述 给定区间[L, R](L <= R <= 2147483647,R-L <= 1000000),请计算区间中素数的个数. 输入 两个数 L 和 R. 输出 一行,区间中素数 ...