Android 手机拍照,录像是必备的功能
1、camera 是拍照的关键类,借助这个类,可以很方便的实现我们的拍照功能
下面来详细的代码:
需要的权限:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO"></uses-permission>
activity 代码:
<SurfaceView
android:layout_width="300dp"
android:layout_height="400dp"
android:id="@+id/sfv_camera_surface"
/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="takePhoto"
android:background="@android:drawable/ic_menu_camera"
/>
界面简单的弄了一个surfaceView和一个Button
接下来初始化控件
java 代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera);
sfv_camera_surface = (SurfaceView) findViewById(R.id.sfv_camera_surface);
sfv_camera_surface.getHolder().addCallback(new Callback() {
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
if (camera != null) {
camera.stopPreview();
camera.release();
camera = null;
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
// 打开相机
initPreview();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// TODO Auto-generated method stub
}
});
}
/**
* 初始化相机
*/
public void initPreview() {
camera = Camera.open(CameraInfo.CAMERA_FACING_BACK);
// 将画面展示到surfaceView上
try {
camera.setPreviewDisplay(sfv_camera_surface.getHolder());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
setCameraDisplayOrientation(this, CameraInfo.CAMERA_FACING_BACK, camera);
// 开启预览效果
camera.startPreview();
}
/**
* 该方法参考 android中Camera setDisplayOrientation使用
* http://blog.csdn.net/fengye810130/article/details/11614427
*
* @param activity
* @param cameraId
* @param camera
*/
public static void setCameraDisplayOrientation(Activity activity, int cameraId, android.hardware.Camera camera) {
android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
android.hardware.Camera.getCameraInfo(cameraId, info);
int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
int degrees = 0;
switch (rotation) {
case Surface.ROTATION_0:
degrees = 0;
break;
case Surface.ROTATION_90:
degrees = 90;
break;
case Surface.ROTATION_180:
degrees = 180;
break;
case Surface.ROTATION_270:
degrees = 270;
break;
}
int result;
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
result = (info.orientation + degrees) % 360;
result = (360 - result) % 360; // compensate the mirror
} else {
// back-facing
result = (info.orientation - degrees + 360) % 360;
}
camera.setDisplayOrientation(result);
}
上面已经把相机打开并投影到surfaceView上
接下来拍照就比较简单了
实现PictureCallback接口
/**
* takePhoto
*
* @param view
*/
public void takePhoto(View view) {
camera.takePicture(null, null, new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
// TODO Auto-generated method stub
// 技术:图片压缩技术
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
try {
FileOutputStream fos = new FileOutputStream(
"/mnt/sdcard/DCIM/Camera/" + System.currentTimeMillis() + ".jpg");
bitmap.compress(Bitmap.CompressFormat.JPEG, 85, fos);
// fos.write(data);
//停止
camera.stopPreview();
//再次开启
camera.startPreview();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
2、录像
首先实例化媒体录制器
然后在点击开始按钮时,设置媒体录制器的参数(具体参数查看API)
java 代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recorder);
sfv_recorder_video = (SurfaceView)findViewById(R.id.sfv_recorder_video);
//实例化媒体录制器
mediaRecorder = new MediaRecorder();
}
/**
* start recorder video
* @param view
*/
public void start(View view){
mediaRecorder.reset();
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
//设置格式
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
//设置保存路径
mediaRecorder.setOutputFile("/mnt/sdcard/G150820_"+System.currentTimeMillis()+".mp4");
mediaRecorder.setPreviewDisplay(sfv_recorder_video.getHolder().getSurface());
try {
mediaRecorder.prepare();
mediaRecorder.start();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* stop recorder
* @param view
*/
public void stop(View view){
if(mediaRecorder!=null){
mediaRecorder.stop();
mediaRecorder.release();
mediaRecorder=null;
}
}
录制出来的视频可能不是很清楚,不过录制已经没问题,可以在输出路径找到录制的视频