Android Camera开发系列(下)——自定义Camera实现拍照查看图片等功能
Android Camera开发系列(下)——自定义Camera实现拍照查看图片等功能
Android Camera开发系列(上)——Camera的基本调用与实现拍照功能以及获取拍照图片加载大图片
上篇讲的都是一些基本的使用,这篇就来自己定义一个相机了
参照Google API:http://developer.android.com/guide/topics/media/camera.html
我们还是在原来的demo上修改,新增一个button,点击跳转到CameraActivity,我们在CameraActivity内实现我们的自定义相机,这里值得注意的是,我们拍照时要一直捕捉拍照的过程,普通的view肯定不行,google给我们提供了一个view叫做
一.获取相机
这里有个前提,记得添加权限
<uses-permission android:name="android.permission.CAMERA"/>
我们新增一个方法来获取系统的相机实例
/**
* 获取系统相机
*
* @return
*/
private Camera getcCamera() {
Camera camera = null;
try {
camera = Camera.open();
} catch (Exception e) {
camera = null;
}
return camera;
}
这里值得注意的是,camera是废弃的对象,那是因为google新给出来一个新的api
但是其实新出的api只是作为高级使用的时候才会用,一般来讲,我们还是用回以前的api
二.SurfaceView预览
要使用SurfaceView还是要
implements SurfaceHolder.Callback
activity_camera.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<SurfaceView
android:id="@+id/sv"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<Button
android:id="@+id/btn_camera"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="拍照" />
</LinearLayout>
预览图像
/**
* 与SurfaceView传播图像
*/
private void showViews(Camera camera, SurfaceHolder holder) {
// 预览相机,绑定
try {
camera.setPreviewDisplay(holder);
// 系统相机默认是横屏的,我们要旋转90°
camera.setDisplayOrientation(90);
// 开始预览
camera.startPreview();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
释放占用内存
/**
* 释放相机的内存
*/
private void clearCamera() {
// 释放hold资源
if (mCamera != null) {
// 停止预览
mCamera.stopPreview();
mCamera.setPreviewCallback(null);
// 释放相机资源
mCamera.release();
mCamera = null;
}
}
绑定生命周期
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
// 在activity运行时绑定
if (mCamera == null) {
mCamera = getcCamera();
if (sh != null) {
showViews(mCamera, sh);
}
}
}
@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
// activity暂停时我们释放相机内存
clearCamera();
}
SurfaceView回调并同步预览
@Override
public void surfaceCreated(SurfaceHolder holder) {
// 开始预览
showViews(mCamera, sh);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// 重启功能
mCamera.stopPreview();
showViews(mCamera, sh);
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// 释放
clearCamera();
}
写到这里,基本上我们的可以预览了,我们来运行一下
这里因为是模拟器,他只有前置摄像头,本应该旋转270°的,我们只要知道通过以上的方法可以同步预览影像就可以了
拍照保存图片
我们设置拍照这个button的点击事件
btn_camera = (Button) findViewById(R.id.btn_camera);
btn_camera.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// 获取当前相机参数
Camera.Parameters parameters = mCamera.getParameters();
// 设置相片格式
parameters.setPictureFormat(ImageFormat.JPEG);
// 设置预览大小
parameters.setPreviewSize(800, 480);
// 设置对焦方式,这里设置自动对焦
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
mCamera.autoFocus(new AutoFocusCallback() {
@Override
public void onAutoFocus(boolean success, Camera camera) {
// 判断是否对焦成功
if (success) {
// 拍照 第三个参数为拍照回调
mCamera.takePicture(null, null, pc);
}
}
});
}
});
这里的pc是一个回调方法,我们重写
private PictureCallback pc = new PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
// data为完整数据
File file = new File("/sdcard/photo.png");
// 使用流进行读写
try {
FileOutputStream fos = new FileOutputStream(file);
try {
fos.write(data);
// 关闭流
fos.close();
// 查看图片
Intent intent = new Intent(CameraActivity.this,
PhotoActivity.class);
// 传递路径
intent.putExtra("path", file.getAbsolutePath());
startActivity(intent);
finish();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
查看图片
我们拍完照片然后就跳转到PhotoActivity查看图片
activity_photo.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/tv_path"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ImageView
android:id="@+id/iv_photo"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
PhotoActivity
package com.lgl.camera;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.TextView;
public class PhotoActivity extends Activity {
private TextView tv_path;
private ImageView iv_photo;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_photo);
String path = getIntent().getStringExtra("path");
tv_path = (TextView) findViewById(R.id.tv_path);
// 显示路径
tv_path.setText(path);
iv_photo = (ImageView) findViewById(R.id.iv_photo);
// 调整角度
try {
FileInputStream fis = new FileInputStream(path);
Bitmap bitmap = BitmapFactory.decodeStream(fis);
// 矩阵
Matrix matrix = new Matrix();
matrix.setRotate(90);
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
bitmap.getHeight(), matrix, true);
iv_photo.setImageBitmap(bitmap);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
我们运行一下
拍完之后跳转到PhotoActivity界面
但是相机是一个大坑,各种不兼容,而且还有前后置摄像头之分哟,上面代码病没有提及前置,前置需要翻转270°,并且我们之前就应该判断是否是前置,再进行旋转,这个只是初学的示例代码,有兴趣的可以下载demo玩玩
Demo下载地址:http://download.csdn.net/detail/qq_26787115/9419048
Android Camera开发系列(下)——自定义Camera实现拍照查看图片等功能的更多相关文章
- Android Camera开发系列(上)——Camera的基本调用与实现拍照功能以及获取拍照图片加载大图片
Android Camera开发系列(上)--Camera的基本调用与实现拍照功能以及获取拍照图片加载大图片 最近也是在搞个破相机,兼容性那叫一个不忍直视啊,于是自己翻阅了一些基本的资料,自己实现了一 ...
- Android 快速开发系列 打造万能的ListView GridView 适配器
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38902805 ,本文出自[张鸿洋的博客] 1.概述 相信做Android开发的写 ...
- Android商城开发系列(四)——butterknife的使用
在上一篇博客:Android商城开发系列(三)——使用Fragment+RadioButton实现商城底部导航栏实现商城的底部导航栏时,里面用到了butterknife,今天来讲解一下的butterk ...
- Android GIS开发系列-- 入门季(14)FeatureLayer之范围查询
Android GIS开发系列-- 入门季(5),这篇文章中,我们知道如何去查找要素.现在有一个需求,查找某点5000米范围的要素,那如何来做呢?首先我们需要在地图上画个5000米半径的圆,然后根据Q ...
- Android应用开发按下返回键退向后台执行
转载请注明来源:http://blog.csdn.net/kjunchen/article/details/50429694 Android应用开发按下返回键退向后台执行 我们日常使用的非常多Andr ...
- Android开发系列(二十二):AdapterViewFlipper的功能和使用方法
AdapterViewFlipper继承了AdapterViewAnimator,它会显示一个View组件,能够通过showPrevious()和showNext()方法控制组件显示上一个.下一个组件 ...
- Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例 本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显示出来,该例子也会涉及到Android加载大图片时候的处理 ...
- Android Studio开发基础之自定义View组件
一般情况下,不直接使用View和ViewGroup类,而是使用使用其子类.例如要显示一张图片可以用View类的子类ImageView,开发自定义View组件可分为两个主要步骤: 一.创建一个继承自an ...
- Android快速开发系列 10个常用工具类
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38965311,本文出自[张鸿洋的博客] 打开大家手上的项目,基本都会有一大批的辅 ...
随机推荐
- Scheme call/cc 研究
目前尚不清楚实质,但已经能够从形式上理解它的某些好处,有个很简单的连乘函数可以说明: 为了展示究竟发生了什么,我包装了下乘法函数,将其变为mul. 我们将比较product和xproduct的区别. ...
- Linux下C/C++程序调试基础(GCC,G++,GDB,CGDB,DDD)
在写程序的时候,经常会遇到一些问题,比如某些变量计算结果不是我们预期的那样,这时我们需要对程序进行调试.本文主要介绍调试C/C++在Linux操作系统下主要的调试工具. 在Linux下写程序,C/C+ ...
- 学习Android路上的一些感慨和总结,慢慢来,比较快!
学习Android路上的一些感慨和总结,慢慢来,比较快! 一直想对自己的学习路程做一个总结,来告别某一个阶段的过去,迎接某一个阶段的来临,一直抽不出时间来,于是零零散散的写了点-,到现在,也已经积攒了 ...
- XMPP(一)-openfire服务端的安装和搭建
XMPP全称:可扩展通讯和表示协议 简介:可扩展通讯和表示协议 (XMPP) 可用于服务类实时通讯.表示和需求响应服务中的XML数据元流式传输.XMPP以Jabber协议为基础,而Jabber是即时通 ...
- UNIX网络编程——ioctl 函数的用法详解
1.介绍 Linux网络程序与内核交互的方法是通过ioctl来实现的,ioctl与网络协议栈进行交互,可得到网络接口的信息,网卡设备的映射属性和配置网络接口.并且还能够查看,修改,删除ARP高速缓存的 ...
- 如何将Ubuntu部署到U盘中,用U盘安装linux操作系统
http://jingyan.baidu.com/article/d5c4b52be79960da560dc59f.html 用U盘装一个linux系统是非常简单的事情,不会就看看这篇文章吧,后期我会 ...
- 【ShaderToy】基础篇之再谈抗锯齿(antialiasing,AA)
写在前面 在之前的基础篇中,我们讲到了在绘制点线时如何处理边缘的锯齿,也就是使用smoothstep函数.而模糊参数是一些定值,或者是跟屏幕分辨率相关的数值,例如分辨率宽度的5%等等.但这种方法其实是 ...
- unix os下du df简单用法
转自:http://dadoneo.iteye.com/blog/984963 du命令参数详解见:http://baike.baidu.com/view/43913.htm 下面我们只对其做简单介绍 ...
- SQL 2012 Always On 为 MSCRMSqlClrLogin SQL 登录名创建非对称密钥时报语法错误
根据实施手册中的下图的SQL在为MSCRMSqlClrLogin 创建非对称秘钥时报语法错误,具体的错误在就path那,调了多次还是报错,索性就把SQL拆开执行. 先执行这条 SELECT * FRO ...
- UNIX环境高级编程——存储映射I/O(mmap函数)
共享内存可以说是最有用的进程间通信方式,也是最快的IPC形式,因为进程可以直接读写内存,而不需要任何数据的拷贝.对于像管道和消息队列等通信方式,则需要在内核和用户空间进行四次的数据拷贝,而共 ...