1.自定义SurfaceView
SurfaceView是一个跟TextView、ImageView同等的控件,我们可以自定义TextView等,当然也可以自定义SurfaceView。在引用的时候,只需写出自定义SurfaceView的全类名即可。
新建CameraView类,继承自SurfaceView
public class CameraView extends SurfaceView implements
android.view.SurfaceHolder.Callback {
Camera camera;
SurfaceHolder holder;
Parameters para;
/**
* @描述 官方文档说raw是未经压缩的图像数据,尝试着去写,但是未能成功
* 小提示 (NOTE: the data will be null if there
* is no raw image callback buffer available or the raw image callback
* buffer is not large enough to hold the raw image)
* */
PictureCallback rawCallback = new PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
camera.stopPreview();
savePhoto(data);
camera.startPreview();
}
//这样的写入照片是错误的,无法载入图片
private void savePhoto(byte[] data) {
String dirPath = Environment.getExternalStorageDirectory()
.getAbsolutePath() + "/AAcamera/";
File dirFile = new File(dirPath);
if (!dirFile.exists()) {
dirFile.mkdirs();
}
String fileName = String.valueOf(System.currentTimeMillis())
+ ".jpeg";
System.out.println(dirPath);
File file = new File(dirPath + fileName);
FileOutputStream fos;
if (!file.exists()) {
try {
file.createNewFile();
FileInputStream fis = new FileInputStream(new String(data));
fos = new FileOutputStream(file);
int len = -1;
while((len = fis.read())!= -1){
fos.write(data, 0, len);
}
fis.close();
fos.flush();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
};
/**
*
* @描述 jpeg callback 在此保存jpeg格式的图片
* */
PictureCallback jpegCallback = new PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
camera.stopPreview();
savePhoto(data);
camera.startPreview();
}
private void savePhoto(byte[] data) {
Bitmap bm = null;
if (data != null) {
bm = BitmapFactory.decodeByteArray(data, 0, data.length);
String dirPath = Environment.getExternalStorageDirectory()
.getAbsolutePath() + "/AAcamera/";
File dirFile = new File(dirPath);
if (!dirFile.exists()) {
dirFile.mkdirs();
}
String fileName = String.valueOf(System.currentTimeMillis())
+ ".jpeg";
System.out.println(dirPath);
File file = new File(dirPath + fileName);
FileOutputStream fos;
if (!file.exists()) {
try {
file.createNewFile();
fos = new FileOutputStream(file);
bm.compress(CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
};
public CameraView(Context context) {
super(context);
}
public CameraView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public CameraView(Context context, AttributeSet attrs) {
super(context, attrs);
holder = this.getHolder();
// holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);//已经废除,去掉不会报错
holder.addCallback(this);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
//这几个参数设置并未看到效果
/* para = camera.getParameters();
para.setPictureSize(1024, 768);
para.setPictureFormat(PixelFormat.JPEG);
para.setFlashMode(Parameters.FLASH_MODE_ON);
para.setPreviewSize(1024, 768);*/
camera.startPreview();
}
public void takePhoto() {
camera.takePicture(null, null, null, jpegCallback);
// camera.takePicture(null, null, raw, null);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
camera = Camera.open(0);//如果有多个摄像头,这里可以设置成不同的摄像头
camera.setPreviewDisplay(holder);
} catch (IOException e) {
e.printStackTrace();
camera.release();
camera = null;
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
camera.release();
}
}
在布局文件中去使用
<com.saya.mycamera.CameraView android:id="@+id/cv" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="0.58" />
今天很长一段时间,我这样使用都报错,说我包含这个控件的xml有问题,原来我在CameraView中只写了
public CameraView(Context context) {
super(context);
}
这个构造方法,把这个带属性的构造方法加上就可以使用了。
public CameraView(Context context, AttributeSet attrs) {
super(context, attrs);
holder = this.getHolder();
// holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);//已经废除,去掉不会报错
holder.addCallback(this);
}
在Activity中去使用
public class CameraActivity extends Activity implements OnClickListener {
private CameraView cv;
private Button takePhoto;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera);
cv = (CameraView) findViewById(R.id.cv);
takePhoto = (Button) findViewById(R.id.takePhoto);
takePhoto.setOnClickListener(this);
}
@Override
public void onClick(View v) {
cv.takePhoto();
}
}
存储原始文件,以及照片的设置还没有成功,明天继续。