今天来学习自定义Camera
实现相机拍照功能
拍照界面:
因为取景框要有实时刷新的效果所以普通的view不行,一般使用surfaceView
上面的按钮是拍照按钮
<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="com.example.cameratest1.MyCamera" >
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="capture"
android:text="Capture" />
<SurfaceView
android:id="@+id/preview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
然后写一个Activity实现拍照的逻辑控制,MyCamera,
实现几个方法
拍照按钮点击事件
public void capture(View view){}
获取Camera对象方法
private Camera getCamera(){}
开始预览相机内容方法,将Camera与SurfaceView进行绑定,
使Camera的实时预览效果显示在SurfaceView
中
private void setStartPreview(Camera camera,SurfaceHolder holder){}
* 释放系统相机资源
private void releaseCamera(){}
全部代码
public class MyCamera extends Activity implements SurfaceHolder.Callback{
private Camera mCamera;
private SurfaceView mPreview;
private SurfaceHolder mHolder;
private Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
// TODO Auto-generated method stub
//这里的data是真实图片数据不是缩略图
File tempFile = new File("/sdcard/tddemp.png");
try {
FileOutputStream fos = new FileOutputStream(tempFile);
fos.write(data);//将拍到的数据写入文件
fos.close();
//将拍到的数据传递到resultActivity中显示出来
Intent intent = new Intent(MyCamera.this, ResultActivity.class);
intent.putExtra("picPath", tempFile.getAbsolutePath());
startActivity(intent);
MyCamera.this.finish();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_camera);
mPreview = (SurfaceView) findViewById(R.id.preview);
mHolder = mPreview.getHolder();
mHolder.addCallback(this);
}
public void capture(View view){
//设置拍照参数
Camera.Parameters parameters = mCamera.getParameters();
parameters.setPictureFormat(ImageFormat.JPEG);//设置拍照格式
parameters.setPictureSize(800, 400);//设置拍照大小
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);//设置自动对焦
//获取最清晰的焦距
mCamera.autoFocus(new Camera.AutoFocusCallback() {
@Override
public void onAutoFocus(boolean success, Camera camera) {
// TODO Auto-generated method stub
if (success) {
mCamera.takePicture(null, null, mPictureCallback);
//第三个参数是回调方法
}
}
});
}
/**
* 使用系统相机需要以下方法
*/
/**
* 获取Camera对象
* @return
*/
private Camera getCamera(){
//这里使用导入的是硬件的Camera,import android.hardware.Camera;
Camera camera;
camera = Camera.open();
return camera;
}
/**
* 开始预览相机内容,将Camera与SurfaceView进行绑定,
* 使Camera的实时预览效果显示在SurfaceView
* 中
*/
private void setStartPreview(Camera camera,SurfaceHolder holder){
try {
camera.setPreviewDisplay(holder);
camera.startPreview();
camera.setDisplayOrientation(90);//系统默认显示横屏的Camera,旋转为竖屏
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 释放系统相机资源
*/
private void releaseCamera(){
if (mCamera!=null) {
mCamera.setPreviewCallback(null);//去掉回调,取消与SuferView的关联
mCamera.stopPreview();//停止取景
mCamera.release();
mCamera =null;
}
}
/**
* 将Camera的生命周期与Activity的生命周期进行绑定
*/
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
if (mCamera == null) {
mCamera = getCamera();
if(mHolder != null){
setStartPreview(mCamera, mHolder);
}
}
}
@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
releaseCamera();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
//重启
mCamera.stopPreview();
setStartPreview(mCamera, mHolder);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
setStartPreview(mCamera, mHolder);
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
releaseCamera();
}
}
写一个ResultActivity,这样在拍照界面点击拍照按钮后,将图片在ResultActivtiy中获取显示
public class ResultActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_result);
String path = getIntent().getStringExtra("picPath");
ImageView imageView = (ImageView) findViewById(R.id.pic);
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);
imageView.setImageBitmap(bitmap);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// Bitmap bitmap = BitmapFactory.decodeFile(path);
// imageView.setImageBitmap(bitmap);
}
}
ResultActivity界面布局:
<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="com.example.cameratest1.ResultActivity" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Capture result"
android:textSize="20sp" />
<ImageView
android:id="@+id/pic"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="center" />
</LinearLayout>
在MainActivity中点击拍照按钮进行拍照:
public void openmyCamera(View view){
//打开自定义的相机
startActivity(new Intent(this,MyCamera.class));
}
然后进入MyCamera界面进行拍照取景,点击确定后将拍到的图片在ResultActivity中显示
一共涉及3个Activity