第一种方式,通过按拍照键实现PictureCallback接口的方式来拍照。这种方式是非常普遍的,网上也存在很多Demo。当遇到红米手机时,照片的尺寸变成了176x144,很小很模糊,而天语的尺寸则是640x480,三星的图片尺寸是1920x1080。为甚么唯独红米的照片尺寸是最小的尺寸?于是在设置Camrea.Paramter参数时,对预览尺寸和照片尺寸进行设置,最终结果没有什么变化。难道是传递的设置这两个属性的参数值,手机不支持。我把天语,三星和红米手机所支持的尺寸全部打印出来,选取了三者都支持的尺寸,一番测试后,仍然没有效果。网上也有人说,有些手机不支持设置设两个属性。但问题总要解决吧,我不知道红米为什么会出现这样的情况,怎么解决呢?那么只有才去其他方式进行拍照了。也就是第二种方式。‘
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.PictureCallback;
import android.os.Bundle;
import android.util.Log;
import android.view.Display;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageView;
import com.lovo.bean.PictureBean;
import com.lovo.police.R;
import com.lovo.ui.widget.CameraGallery;
import com.lovo.ui.widget.PictureImageView;
import com.lovo.util.ImageUtils;
/**
* 拍照的界面
*
*/
public class CameraActivity extends Activity implements PictureCallback,Callback,OnClickListener {
private SurfaceView surfaceView;
private SurfaceHolder surfaceHolder;
private Camera camera;
private int width;
private int height;
private boolean isPreview;
private CameraGallery cameraGallery;
private ImageView takePictureImageView;
private Button okBtn;
private Button cancelBtn;
private Display display;
private List<PictureBean> pictureBeanList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.camera_main);
ImageUtils.loadImages(this);
surfaceView = (SurfaceView) findViewById(R.id.camera_main_sv);
takePictureImageView = (ImageView) findViewById(R.id.camera_main_iv_takepic);
takePictureImageView.setOnClickListener(this);
okBtn = (Button) findViewById(R.id.camera_main_btn_ok);
cancelBtn = (Button) findViewById(R.id.camera_main_btn_cancel);
okBtn.setOnClickListener(this);
cancelBtn.setOnClickListener(this);
// 获取屏幕可显示大小
WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
display = wm.getDefaultDisplay();
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
// 设置该SurfaceView自己不缓冲数据
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
cameraGallery = (CameraGallery) findViewById(R.id.cameraPictureGallery1);
pictureBeanList = (List<PictureBean>) getIntent().getSerializableExtra("picList");
for(int i = 0;i < pictureBeanList.size();i++){
cameraGallery.addImage(pictureBeanList.get(i));
}
cameraGallery.showImage();
cameraGallery.setGalleryOffset();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (camera != null) {
camera.stopPreview();
Parameters parameters = camera.getParameters();
resetCameraSize(parameters);
camera.startPreview();
// 自动对焦
camera.autoFocus(null);
}
cameraGallery.setGalleryOffset();
}
public void initCamera(){
if (camera != null && !isPreview) {
try {
Camera.Parameters parameters = camera.getParameters();
//设置闪光灯为自动
parameters.setFlashMode(Parameters.FLASH_MODE_AUTO);
camera.setParameters(parameters);
resetCameraSize(parameters);
// 设置每秒显示4帧
// parameters.setPreviewFrameRate(4);
// 设置图片格式
parameters.setPictureFormat(PixelFormat.JPEG);
// 设置JPG照片的质量
parameters.set("jpeg-quality", 80);
// android2.3后不需要下面代码
// camera.setParameters(parameters);
// 通过SurfaceView显示取景画面
camera.setPreviewDisplay(surfaceHolder);
// 开始预览
camera.startPreview();
// 自动对焦
camera.autoFocus(null);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
isPreview = true;
}
}
@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
if (camera != null) {
if (isPreview) {
camera.stopPreview();
isPreview = false;
}
}
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
if (camera != null) {
if (!isPreview) {
camera.startPreview();
// 自动对焦
camera.autoFocus(null);
isPreview = true;
}
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
initCamera();
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
if (!isPreview) {
// 打开摄像头
camera = Camera.open();
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (camera != null) {
if (isPreview) {
camera.stopPreview();
}
camera.release();
camera = null;
}
}
@Override
public void onClick(View v) {
if(v == takePictureImageView){
//拍照
camera.takePicture(null, null, this);
}
if(v == okBtn){
//点击确定后将拍好的照片返回给录入界面
ArrayList<PictureImageView> picList = (ArrayList) cameraGallery.getPicList();
ArrayList picBeanList = new ArrayList();
for (int i = 0; i < picList.size(); i++) {
picBeanList.add(picList.get(i).getPictureBean());
}
Intent intent = new Intent();
Bundle bundle = new Bundle();
bundle.putSerializable("picList", picBeanList);
intent.putExtras(bundle);
setResult(0, intent);
finish();
}
if(v == cancelBtn){
setResult(1);
finish();
}
}
/**
* 开始拍照
*/
@Override
public void onPictureTaken(byte[] data, Camera camera) {
//保存照片
ImageUtils.isFromCaream=true;
PictureBean pb = ImageUtils.savePicture(this, data,true);
//将照片设置给Gallery
cameraGallery.addImage(pb);
if (camera != null) {
camera.stopPreview();
camera.startPreview();
// 自动对焦
camera.autoFocus(null);
isPreview = true;
}
}
/**
* 旋转相机和设置预览大小
* @param parameters
*/
public void resetCameraSize(Parameters parameters){
if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {
// 如果是竖屏
camera.setDisplayOrientation(90);
} else {
camera.setDisplayOrientation(0);
}
width = display.getWidth();
height = display.getHeight();
// 设置预览的大小
parameters.setPreviewSize(width, height);
// 设置照片大小
parameters.setPictureSize(width, height);
}
// @Override
// protected void onDestroy() {
// super.onDestroy();
// ImageUtils.clearImageFile(pictureBeanList);
// }
}
第二种方式,通过实现Camera.PreviewCallback接口,重写public void onPreviewFrame(byte[] data, Camera camera) { }方法。当相机正在预览的时候,按下拍照按钮,取出预览那一张图像,相当于截取预览区域的图像。注意这里面的byte[] data不能直接转换成Bitmap,否则会出现空指针异常,而且图片的大小事0B。只有通过android提供的YuvImage类来压缩成图片。我这里进行了把照片宽高按照4:3的比例来计算。当然,这里获得的Size对象,各个手机的宽高都不一致,但是他们取出来的照片尺寸都很大。符合项目要求。
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
mByte = data;
}
private void saveBitmap(){
try {
Camera.Parameters parameters = mCamera.getParameters();
Size size = parameters.getPreviewSize();
YuvImage image = new YuvImage(mByte, parameters.getPreviewFormat(),
size.width, size.height, null);
File file = new File(Util.PHOTO_TEMP);
FileOutputStream filecon = new FileOutputStream(file);
//按4:3来缩放图片
int width = image.getWidth();
int height = image.getHeight();
int iWidth;
int iHeigth;
iHeigth = (width*3)/4;
if(iHeigth>=height){
iHeigth = height;
iWidth = (height*4)/3;
}else{
iWidth = width;
}
image.compressToJpeg(
new Rect(0, 0, iWidth, iHeigth), 100,
filecon);
} catch (Exception e) {
}
}