第一步:拍照预览 自定义相机(一)
第二步:相机参数设置、对焦实现、拍照存储在本地、拍照声音、闪光灯、图片缩放与旋转
上一步,我们完成了相机的预览,但是显示有问题。接下来我们将解决这些问题:
主要涉及:
Camera类
AutoFocusCallback、PictureCallback回调
在Activity中设置相机参数,调整拍照状态。
都在Activity中
//开始预览相机
private void openCamera(){
if (camera==null){
//获取相机实例
camera=camera.open();
//获取相机参数实例
Camera.Parameters parameters=camera.getParameters();
//将相机顺时针旋转90度
camera.setDisplayOrientation(90);
//设置输出图片类型
parameters.setPictureFormat(ImageFormat.JPEG);
//获取默认照片和相机尺寸 private List<Size> photoSizes, previewSizes;
photoSizes=camera.getParameters().getSupportedPictureSizes();
//从大到小还是从小到大顺序
boolean isF = photoSizes.get(0).width < photoSizes.get(photoSizes
.size() - 1).width;
for (Size size : photoSizes) {
System.out.println("width:" + size.width + "-height:"
+ size.height);
if (isF) {
//设置width:2048-height:1536 图片大小
if (size.width > 1800) {
parameters.setPictureSize(size.width, size.height);
break;
}
} else {
if (size.width < 2000) {
parameters.setPictureSize(size.width, size.height);
break;
}
}
}
previewSizes = parameters.getSupportedPreviewSizes();
boolean isFp = previewSizes.get(0).width < previewSizes
.get(previewSizes.size() - 1).width;
for (Size size : previewSizes) {
System.out.println("width:" + size.width + "-height:"
+ size.height);
if (isFp) {
//设置width:1920-height:1088 预览
if (size.width > 1800) {
parameters.setPreviewSize(size.width, size.height);
break;
}
} else {
if (size.width < 2000) {
parameters.setPreviewSize(size.width, size.height);
break;
}
}
}
camera.setParameters(parameters);
if (container==null) {
container = (LinearLayout) findViewById(R.id.ll_contain);
}
cameraPreview=new CameraPreview(CameraActivity.this,camera);
container.addView(cameraPreview);
}
}
//自动对焦回调
private Camera.AutoFocusCallback afcb =new Camera.AutoFocusCallback() {
@Override
public void onAutoFocus(boolean success, Camera camera) {
//对焦状态
isFoucs=success;
if (success){
//对焦成功的样式图片
iv_camera.setBackgroundResource(R.drawable.ic_focus_successed);
try{
camera.takePicture(null,null,pcb);
}catch (Exception e){
e.printStackTrace();
}
}else {
//对焦失败的样式图片
iv_camera.setBackgroundResource(R.drawable.ic_focus_failed);
}
}
};
private Camera.PictureCallback pcb=new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
//播放系统拍照声音
shootSound();
isFoucs = false;
iv_camera.setBackgroundResource(R.drawable.ic_focusing_begin);
//得到文件路径
String path = getPhotoPath();
//相片高度及默认高度
int height = camera.getParameters().getPictureSize().height;
if (height <= 0) {
height = 320;
}
camera.startPreview();
photosList.add(path);
//输出文件流
addPhoto(path,data);
}
};
private void addPhoto(String path,byte[] data){
if (path!=null){
try {
FileOutputStream os=new FileOutputStream(path);
os.write(data);
os.close();
}catch (Exception e){
e.printStackTrace();
}
}
File file=new File(path);
if (file!=null){
Bitmap bitmap= BitmapUtils.getSamllerBitmap(path,200,200);
bitmap=BitmapUtils.rotateBitmap(bitmap,90);//BitmapUtils.getBitmapAngle(path)
iv_show.setImageBitmap(bitmap);
}else {
Toast.makeText(CameraActivity.this,"显示照片失败!",Toast.LENGTH_SHORT);
}
}
/**
* 播放系统拍照声音
*/
public void shootSound() {
AudioManager meng = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
int volume = meng.getStreamVolume(AudioManager.STREAM_NOTIFICATION);
if (volume != 0) {
MediaPlayer shootMP = null;
if (shootMP == null)
shootMP = MediaPlayer
.create(this,
Uri.parse("file:///system/media/audio/ui/camera_click.ogg"));
if (shootMP != null)
shootMP.start();
}
}
private String getPhotoPath(){
if (photoPath==null){
photoPath = Environment.getExternalStorageDirectory().getPath() + "/test1/photo/";
File file = new File(photoPath);
if (!file.exists()) {
file.mkdirs();
}
}
return photoPath+ System.currentTimeMillis()+".jpg";
}
public void onClick(View v) {
switch (v.getId()){
case R.id.btn_camera:
if (isFoucs){
camera.takePicture(null,null,pcb);
}else {
camera.autoFocus(afcb);
}
break;
}
}
// Camera.Parameters params = camera.getParameters();
// // 开启闪光灯
// params.setFlashMode(Camera.Parameters.FLASH_MODE_ON);
// // 关闭闪光灯
// params.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
图片缩放和旋转
//图片帮助类
public class BitmapUtils {
//计算图片的缩放值
public static int calculateinSampleSize(BitmapFactory.Options options,int reqWidth,int reqHeight){
final int width =options.outWidth;
final int height =options.outHeight;
int inSampleSize =1;
if (reqHeight<height||reqWidth<width){
final int widthRadio=Math.round((float) width/(float)reqWidth);
final int heightRadio=Math.round((float) height/(float)reqHeight);
inSampleSize=widthRadio<heightRadio?widthRadio:heightRadio;
}
return inSampleSize;
}
// 根据路径获得图片并压缩,返回bitmap用于显示
public static Bitmap getSamllerBitmap(String path,int reqWidth,int reqHeight){
final BitmapFactory.Options options=new BitmapFactory.Options();
//只加载图像框架
options.inJustDecodeBounds=true;
BitmapFactory.decodeFile(path,options);
options.inSampleSize=calculateinSampleSize(options,reqWidth,reqHeight);
//设置加载全部图像内容
options.inJustDecodeBounds=false;
return BitmapFactory.decodeFile(path,options);
}
//旋转照片
public static Bitmap rotateBitmap(Bitmap bitmap,int angle){
if (null!=bitmap){
Matrix matrix=new Matrix();
matrix.postRotate(angle);
bitmap=Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(),bitmap.getHeight(),matrix,true);
}
return bitmap;
}
//得到照片旋转角度
public static int getBitmapAngle(String path){
int angle=0;
try {
ExifInterface exifInterface=new ExifInterface(path);
int orientation =exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
switch (orientation){
case ExifInterface.ORIENTATION_ROTATE_90:
angle=90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
angle=180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
angle=270;
break;
}
} catch (IOException e) {
e.printStackTrace();
}
return angle;
}
}