Android Camera开发系列(上)——Camera的基本调用与实现拍照功能以及获取拍照图片加载大图片
最近也是在搞个破相机,兼容性那叫一个不忍直视啊,于是自己翻阅了一些基本的资料,自己实现了一个相机,虽然相机这东西,兼容性不敢恭维,但是用到的地方确实很多,所以今天,我们就一起来学习一下吧
参照Google API:http://developer.android.com/guide/topics/media/camera.html
一.Camera的启动方式
1.调用系统方式
2.自定义相机
二.调用系统相机
喜闻乐见,调用系统相机是十分的简单的,我们这里演示的话,还是新建一个工程吧,这里就直接用Eclipse开发了,这里我们新建一个项目——SystemCamera
activity_main.xml
这里直接一个button就够了
<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" >
<Button
android:id="@+id/on_camera"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="打开相机" />
</RelativeLayout>
MainActivity
package com.lgl.camera;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity {
private Button on_camera;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
on_camera = (Button) findViewById(R.id.on_camera);
on_camera.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
/**
* 我们使用Intent的方式打开系统相机
* 1.直接跳转相机包名,前提是你知道这个应用的包名
* 2.就是使用隐式Intent了,在这里我们就使用隐式intent
*/
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); //指定拍照
startActivity(intent);
}
});
}
}
好的,我们来运行一下吧
三.获取拍照图片
说到获取图片,大家应该就立马想到了startActivityForResult,没错,我们就是这样直接拿到传递回来的data,然后通过Bundle转换二进制流的方式获得一个bitmap,好的,这样的话,我们就要新增加一个imageview了
activity_main.xml
<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" >
<Button
android:id="@+id/on_camera"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="打开相机" />
<ImageView
android:id="@+id/iv_photo"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
MainActivity
package com.lgl.camera;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
public class MainActivity extends Activity {
private Button on_camera;
private ImageView iv_photo;
// 返回码
private static final int CODE = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv_photo = (ImageView) findViewById(R.id.iv_photo);
on_camera = (Button) findViewById(R.id.on_camera);
on_camera.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
/**
* 我们使用Intent的方式打开系统相机
* 1.直接跳转相机包名,前提是你知道这个应用的包名
* 2.就是使用隐式Intent了,在这里我们就使用隐式intent
*/
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); // 指定拍照\
// 拍照返回图片
startActivityForResult(intent, CODE);
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
// 判断是否返回值
if (resultCode == RESULT_OK) {
// 判断返回值是否正确
if (requestCode == CODE) {
// 获取图片
Bundle bundle = data.getExtras();
// 转换图片的二进制流
Bitmap bitmap = (Bitmap) bundle.get("data");
// 设置图片
iv_photo.setImageBitmap(bitmap);
}
}
}
}
好,我们继续运行一下
加载大图片
这里我们要知道一个概念,就是我们返回结果是从data中取出来的,但是这个data不可能存储太多的东西,比如你拍的4K照片,动辄几十M,那不就直接挂了嘛,google是这样设定的,data返回的只是有一个缩略图,但是我们实际开发当中怎么可以使用缩略图,别急,是有办法的
我们再增加一个button和一个imageview为了显示真实大小的图片,这里就直接上完整代码了,思路十分的顺,但是我们所用到的方式是要写sd卡的,我们新增加一个权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
接着我们就可以在他返回请求的时候请求另一个返回码了
activity_main.xml
<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" >
<Button
android:id="@+id/on_camera"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="打开相机" />
<Button
android:id="@+id/on_camera_big"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="大图片" />
<ImageView
android:id="@+id/iv_photo"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ImageView
android:id="@+id/iv_photo_big"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
MainActivity
package com.lgl.camera;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
public class MainActivity extends Activity {
private Button on_camera;
private ImageView iv_photo;
private Button on_camera_big;
private ImageView iv_photo_big;
// 返回码
private static final int CODE = 1;
private static final int CODEBIG = 2;
// 记录文件保存位置
private String mFilePath;
private FileInputStream is = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 获取SD卡路径
mFilePath = Environment.getExternalStorageDirectory().getPath();
// 文件名
mFilePath = mFilePath + "/" + "photo.png";
iv_photo = (ImageView) findViewById(R.id.iv_photo);
iv_photo_big = (ImageView) findViewById(R.id.iv_photo_big);
on_camera = (Button) findViewById(R.id.on_camera);
on_camera.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
/**
* 我们使用Intent的方式打开系统相机
* 1.直接跳转相机包名,前提是你知道这个应用的包名
* 2.就是使用隐式Intent了,在这里我们就使用隐式intent
*/
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); // 指定拍照
// 拍照返回图片
startActivityForResult(intent, CODE);
}
});
on_camera_big = (Button) findViewById(R.id.on_camera_big);
on_camera_big.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// 指定拍照
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// 加载路径
Uri uri = Uri.fromFile(new File(mFilePath));
// 指定存储路径,这样就可以保存原图了
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
// 拍照返回图片
startActivityForResult(intent, CODEBIG);
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
// 判断是否返回值
if (resultCode == RESULT_OK) {
// 判断返回值是否正确
if (requestCode == CODE) {
// 获取图片
Bundle bundle = data.getExtras();
// 转换图片的二进制流
Bitmap bitmap = (Bitmap) bundle.get("data");
// 设置图片
iv_photo.setImageBitmap(bitmap);
// 加载原图
} else if (requestCode == CODEBIG) {
try {
// 获取输入流
is = new FileInputStream(mFilePath);
// 把流解析成bitmap
Bitmap bitmap = BitmapFactory.decodeStream(is);
// 设置图片
iv_photo_big.setImageBitmap(bitmap);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
// 关闭流
try {
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
}
好的,最后运行一遍