- 第一种方式,通过按拍照键实现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;
- }
- ate 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) {
- }
- }