安卓高级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加载大图片时候的处理 ...
随机推荐
- append()/extend()/insert()/remove()/del/pop()/slice列表分片
member = ['小甲鱼', 88, '黑夜', 90, '迷途', 85, '怡静', 90, '秋舞斜阳', 88] member.append('字符串')#在列表结尾处增加字符串 memb ...
- Python3NumPy——数组(2)之数学空间与NumPy空间
0 介绍 本文承接上一篇,文章采用新的阐述方式,将数学中的表达与NumPy中的函数关联起来. 采用这种方式,可以直接建立数学表达与计算系统的对应关系,更易理解. 由于博客编写时间有限,每次尝试一个知识 ...
- lsdyna进阶教程-弹性球撞击刚性平板
在lsdyna基础教程中,我们做了一个关于刚性球撞击弹性平板的粒子,现在我们考虑另外一个问题,如果用弹性球撞击刚性地面该怎么做呢?是不是要从头开始建模,操作步骤是不是一样呢?其实很简单,将球和地面的材 ...
- 简单的sql调优(批处理)
最近在写一个java的爬虫程序时,遇到了一个大量数据进行插入更新和大量数据循环查询的问题,所以查了一下一般的调优的方式,下面主要介绍我采取的调优措施. 一 .调优思路 先说说我采取方式的调优的思路,这 ...
- 部署上次的Hapi到Windows+Docker,WindowsDocker
前言: 理论的就不多说了,具体的架构看图.web这里是上篇文章开发的Hapi服务,数据库Mysql,废话不多说,粗略的画了下,架构图如下: Mysql镜像拉取,配置 数据库镜像查找 docker se ...
- [LeetCode] Minimum Window Subsequence 最小窗口序列
Given strings S and T, find the minimum (contiguous) substring W of S, so that T is a subsequence of ...
- jenkins实战(一):war安装及插件安装
一:整体介绍 以下摘自维基百科: Jenkins是一个用Java编写的开源的持续集成工具.在与Oracle发生争执后,项目从Hudson项目复刻. Jenkins提供了软件开发的持续集成服务.它运行在 ...
- 【分享】几篇关于Repository 相关的讨论、提问、文章
一.引入 最近在了解DDD,对于里面Repository 有点疑问和关注.闲来无事,去找了一些文章,来补补.在这里分享出来给大家.文章大多数都是英文的,见谅哈. 二.推荐列表 2.1 Filters ...
- [PA 2014]Bohater
Description 在一款电脑游戏中,你需要打败n只怪物(从1到n编号).为了打败第i只怪物,你需要消耗d[i]点生命值,但怪物死后会掉落血药,使你恢复a[i]点生命值.任何时候你的生命值都不能降 ...
- 计蒜客NOIP2017提高组模拟赛(三)day2-小区划分
传送门 dp,注意边界 #include<cstdio> #include<cstdlib> #include<algorithm> #include<cst ...