Camera一般和SurfaceView一起使用,SurfaceView用来显示摄像头所捕获的影像。
通过findViewById得到SurfaceView对象。
给SurFaceHolder指定类型
在surfaceCreated中获取Camera对象,在surfaceDestroyed中释放Camera对象,在surfaceChanged中设置Camera参数并启动预览功能。
如果要拍照,需调Camera的takePicture(Camera.ShutterCallback shutter, Camera.PictureCallback raw, Camera.PictureCallback postview, Camera.PictureCallback jpeg)
方法,最后一个接口是我们需要的jpg图片信息接口,前三参数全null,实现第四个参数对象接口。接口有一个方法:onPictureTaken(byte[] data,Camera camera),第一个参数是拍照后返回的照片数据byte数组类型,第二个参数是拍照的摄像头。
第一个参数是文件流的byte,可以直接存为一个图片文件。
注意:默认的预览是横屏的,也就是说竖屏手机看预览发现逆时针转了90°,可以设置camera.setDisplayOrientation(90);把屏幕顺时针转90°就正常了。也可以通过设置照相机参数parameters.set("orientation", "portrait");达到同样效果。
通过findViewById得到SurfaceView对象。
SurfaceView surfaceView=(SurfaceView)findViewById(R.id.surfaceView);
SurfaceView一般不直接操作其对象,而是通过
SurfaceHolder holder = surfaceView.getHolder();
方法得到SurfaceHolder对象
给SurFaceHolder指定类型
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);//SurfaceView没有自己的buffer
给SurfaceHolder加上监听,方法:
addCallback(SurfaceHolder.Callback callback)
SurfaceHolder.Callback接口需实现三个方法:
@Override
public void surfaceCreated(SurfaceHolder holder) {
camera=Camera.open();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
Camera.Parameters parameters = camera.getParameters();
parameters.setRotation(90);
camera.setDisplayOrientation(90);
camera.setParameters(parameters);
try {
camera.setPreviewDisplay(holder);
} catch (IOException e) {
e.printStackTrace();
camera.release();
camera=null;
}
camera.startPreview();//开始预览
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
camera.release();
}
在surfaceCreated中获取Camera对象,在surfaceDestroyed中释放Camera对象,在surfaceChanged中设置Camera参数并启动预览功能。
如果要拍照,需调Camera的takePicture(Camera.ShutterCallback shutter, Camera.PictureCallback raw, Camera.PictureCallback postview, Camera.PictureCallback jpeg)
方法,最后一个接口是我们需要的jpg图片信息接口,前三参数全null,实现第四个参数对象接口。接口有一个方法:onPictureTaken(byte[] data,Camera camera),第一个参数是拍照后返回的照片数据byte数组类型,第二个参数是拍照的摄像头。
第一个参数是文件流的byte,可以直接存为一个图片文件。
注意:默认的预览是横屏的,也就是说竖屏手机看预览发现逆时针转了90°,可以设置camera.setDisplayOrientation(90);把屏幕顺时针转90°就正常了。也可以通过设置照相机参数parameters.set("orientation", "portrait");达到同样效果。
不过虽然预览正常了,但拍完照后发现照片逆时针转了90°,解决办法就是在设置参数:
parameters.setRotation(90);
以下为调用系统的照相机功能:
package com.example.camera1;
import java.io.File;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.media.ThumbnailUtils;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
/**调用系统的照相机照相
* 通过ThumbnailUtils类可以处理bitmap类型图片的大小
* */
public class MainActivity extends Activity {
/** Called when the activity is first created. */
private String imgPath = "/sdcard/aaaaaaaaaaa/img.jpg";
private ImageView iViewPic;
private ImageView view2;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
view2=(ImageView)findViewById(R.id.imageView2);
iViewPic=(ImageView)findViewById(R.id.imageView1);
}
public void button(View v){
File vFile = new File(imgPath);
if(!vFile.exists())
{
File vDirPath = vFile.getParentFile(); //new File(vFile.getParent());
vDirPath.mkdirs();
}
Uri uri = Uri.fromFile(vFile);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);//如果传递这个参数,那么拍到的相片会存一份到uri指向的路径
startActivityForResult(intent, 99);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
if (resultCode == RESULT_OK)
{
view2.setImageURI(Uri.fromFile(new File(imgPath)));
}
if (resultCode == RESULT_OK)
{
iViewPic.setImageBitmap(bmp);
System.out.println( "bmp width:" + bmp.getWidth() + ", height:" + bmp.getHeight());
}
super.onActivityResult(requestCode, resultCode, data);
}
}
我在htc g17上测试过发现设置intent.putExtra(MediaStore.EXTRA_OUTPUT, uri)后上面代码会有2个ImageView,不过大小好像不一样,而调用安卓原生的照相机上用这段代码时,发现不能同时获取两个ImageView,拍到的照片非常恶心,一个ImageView是正常的,另一个逆时针转了90°,没怎么详细测试调用的一些细节,毕竟写一个camera也不是很难。
并不是所有手机都能对参数有响应,我就遇到了一款手机照出来的图片不管怎么设置图片就是逆转了90°,这样就只能找其他办法来旋转图片90°了,以下是个旋转图片90度的方法,图片储存在手机上。图片质量越好图片体积越大,小心爆内存不足的异常。
private void savePic(byte[] data) throws FileNotFoundException{
Bitmap bm = BitmapFactory.decodeByteArray(data, 0, data.length);
Matrix matrix = new Matrix();
matrix.setRotate(90);
width = bm.getWidth();
height=bm.getHeight();
bm = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, true);
bm.compress(CompressFormat.JPEG, 80, openFileOutput(new Date().toGMTString(), MODE_WORLD_WRITEABLE));
}