android 自定义相机拍照的两种方式

  1. 第一种方式,通过按拍照键实现PictureCallback接口的方式来拍照。这种方式是非常普遍的,网上也存在很多Demo。当遇到红米手机时,照片的尺寸变成了176x144,很小很模糊,而天语的尺寸则是640x480,三星的图片尺寸是1920x1080。为甚么唯独红米的照片尺寸是最小的尺寸?于是在设置Camrea.Paramter参数时,对预览尺寸和照片尺寸进行设置,最终结果没有什么变化。难道是传递的设置这两个属性的参数值,手机不支持。我把天语,三星和红米手机所支持的尺寸全部打印出来,选取了三者都支持的尺寸,一番测试后,仍然没有效果。网上也有人说,有些手机不支持设置设两个属性。但问题总要解决吧,我不知道红米为什么会出现这样的情况,怎么解决呢?那么只有才去其他方式进行拍照了。也就是第二种方式。‘  
[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. import java.io.IOException;  
  2. import java.util.ArrayList;  
  3. import java.util.List;  
  4.   
  5. import android.app.Activity;  
  6. import android.content.Context;  
  7. import android.content.Intent;  
  8. import android.content.res.Configuration;  
  9. import android.graphics.PixelFormat;  
  10. import android.hardware.Camera;  
  11. import android.hardware.Camera.Parameters;  
  12. import android.hardware.Camera.PictureCallback;  
  13. import android.os.Bundle;  
  14. import android.util.Log;  
  15. import android.view.Display;  
  16. import android.view.SurfaceHolder;  
  17. import android.view.SurfaceHolder.Callback;  
  18. import android.view.SurfaceView;  
  19. import android.view.View;  
  20. import android.view.View.OnClickListener;  
  21. import android.view.WindowManager;  
  22. import android.widget.Button;  
  23. import android.widget.ImageView;  
  24.   
  25. import com.lovo.bean.PictureBean;  
  26. import com.lovo.police.R;  
  27. import com.lovo.ui.widget.CameraGallery;  
  28. import com.lovo.ui.widget.PictureImageView;  
  29. import com.lovo.util.ImageUtils;  
  30.   
  31. /**  
  32.  * 拍照的界面  
  33.  *  
  34.  */  
  35. public class CameraActivity extends Activity implements PictureCallback,Callback,OnClickListener {  
  36.     private SurfaceView surfaceView;  
  37.     private SurfaceHolder surfaceHolder;  
  38.     private Camera camera;  
  39.     private int width;  
  40.     private int height;  
  41.     private boolean isPreview;  
  42.     private CameraGallery cameraGallery;  
  43.     private ImageView takePictureImageView;  
  44.     private Button okBtn;  
  45.     private Button cancelBtn;  
  46.     private Display display;  
  47.     private List<PictureBean> pictureBeanList;  
  48.       
  49.     @Override  
  50.     protected void onCreate(Bundle savedInstanceState) {  
  51.         super.onCreate(savedInstanceState);  
  52.         setContentView(R.layout.camera_main);  
  53.         ImageUtils.loadImages(this);  
  54.         surfaceView = (SurfaceView) findViewById(R.id.camera_main_sv);  
  55.         takePictureImageView = (ImageView) findViewById(R.id.camera_main_iv_takepic);  
  56.         takePictureImageView.setOnClickListener(this);  
  57.           
  58.         okBtn = (Button) findViewById(R.id.camera_main_btn_ok);  
  59.         cancelBtn = (Button) findViewById(R.id.camera_main_btn_cancel);  
  60.         okBtn.setOnClickListener(this);  
  61.         cancelBtn.setOnClickListener(this);  
  62.   
  63.         // 获取屏幕可显示大小  
  64.         WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);  
  65.         display = wm.getDefaultDisplay();  
  66.           
  67.         surfaceHolder = surfaceView.getHolder();  
  68.         surfaceHolder.addCallback(this);  
  69.         // 设置该SurfaceView自己不缓冲数据  
  70.         surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);  
  71.           
  72.         cameraGallery = (CameraGallery) findViewById(R.id.cameraPictureGallery1);  
  73.         pictureBeanList = (List<PictureBean>) getIntent().getSerializableExtra("picList");  
  74.         for(int i = 0;i < pictureBeanList.size();i++){  
  75.             cameraGallery.addImage(pictureBeanList.get(i));  
  76.         }  
  77.         cameraGallery.showImage();  
  78.         cameraGallery.setGalleryOffset();  
  79.     }  
  80.     @Override  
  81.     public void onConfigurationChanged(Configuration newConfig) {  
  82.         super.onConfigurationChanged(newConfig);  
  83.         if (camera != null) {  
  84.             camera.stopPreview();  
  85.             Parameters parameters = camera.getParameters();  
  86.             resetCameraSize(parameters);  
  87.             camera.startPreview();  
  88.             // 自动对焦  
  89.             camera.autoFocus(null);  
  90.         }  
  91.         cameraGallery.setGalleryOffset();  
  92.     }  
  93.     public void initCamera(){  
  94.    
  95.         if (camera != null && !isPreview) {  
  96.             try {  
  97.                 Camera.Parameters parameters = camera.getParameters();  
  98.                 //设置闪光灯为自动  
  99.                 parameters.setFlashMode(Parameters.FLASH_MODE_AUTO);  
  100.                 camera.setParameters(parameters);  
  101.                 resetCameraSize(parameters);  
  102.                    
  103.                 // 设置每秒显示4帧  
  104. //              parameters.setPreviewFrameRate(4);  
  105.                 // 设置图片格式  
  106.                 parameters.setPictureFormat(PixelFormat.JPEG);  
  107.                 // 设置JPG照片的质量  
  108.                 parameters.set("jpeg-quality", 80);  
  109.                   
  110.                 // android2.3后不需要下面代码  
  111.                 // camera.setParameters(parameters);  
  112.                 // 通过SurfaceView显示取景画面  
  113.                 camera.setPreviewDisplay(surfaceHolder);  
  114.                   
  115.                 // 开始预览  
  116.                 camera.startPreview();  
  117.                 // 自动对焦  
  118.                 camera.autoFocus(null);  
  119.             } catch (IOException e) {  
  120.                 // TODO Auto-generated catch block  
  121.                 e.printStackTrace();  
  122.             }  
  123.             isPreview = true;  
  124.         }  
  125.     }  
  126.   
  127.     @Override  
  128.     protected void onPause() {  
  129.         // TODO Auto-generated method stub  
  130.         super.onPause();  
  131.         if (camera != null) {  
  132.             if (isPreview) {  
  133.                 camera.stopPreview();  
  134.                 isPreview = false;  
  135.             }  
  136.         }  
  137.     }  
  138.     @Override  
  139.     protected void onResume() {  
  140.         // TODO Auto-generated method stub  
  141.         super.onResume();  
  142.           
  143.         if (camera != null) {  
  144.             if (!isPreview) {  
  145.                 camera.startPreview();  
  146.                 // 自动对焦  
  147.                 camera.autoFocus(null);  
  148.                 isPreview = true;  
  149.             }  
  150.         }  
  151.     }  
  152.     @Override  
  153.     public void surfaceChanged(SurfaceHolder holder, int format, int width,  
  154.             int height) {  
  155.         initCamera();  
  156.     }  
  157.   
  158.     @Override  
  159.     public void surfaceCreated(SurfaceHolder holder) {  
  160.         if (!isPreview) {  
  161.             // 打开摄像头  
  162.             camera = Camera.open();  
  163.         }  
  164.     }  
  165.   
  166.     @Override  
  167.     public void surfaceDestroyed(SurfaceHolder holder) {  
  168.         if (camera != null) {  
  169.             if (isPreview) {  
  170.                 camera.stopPreview();  
  171.             }  
  172.             camera.release();  
  173.             camera = null;  
  174.         }  
  175.     }  
  176.   
  177.     @Override  
  178.     public void onClick(View v) {  
  179.         if(v == takePictureImageView){  
  180.             //拍照  
  181.             camera.takePicture(null, null, this);  
  182.         }  
  183.         if(v == okBtn){  
  184.             //点击确定后将拍好的照片返回给录入界面  
  185.             ArrayList<PictureImageView> picList = (ArrayList) cameraGallery.getPicList();  
  186.             ArrayList picBeanList = new ArrayList();  
  187.             for (int i = 0; i < picList.size(); i++) {  
  188.                 picBeanList.add(picList.get(i).getPictureBean());  
  189.             }  
  190.             Intent intent = new Intent();  
  191.             Bundle bundle = new Bundle();  
  192.             bundle.putSerializable("picList", picBeanList);  
  193.             intent.putExtras(bundle);  
  194.             setResult(0, intent);  
  195.             finish();  
  196.         }  
  197.         if(v == cancelBtn){  
  198.             setResult(1);  
  199.             finish();  
  200.         }  
  201.     }  
  202.   
  203.     /**  
  204.      * 开始拍照  
  205.      */  
  206.     @Override  
  207.     public void onPictureTaken(byte[] data, Camera camera) {  
  208.         //保存照片  
  209.         ImageUtils.isFromCaream=true;  
  210.         PictureBean pb = ImageUtils.savePicture(this, data,true);  
  211.         //将照片设置给Gallery  
  212.         cameraGallery.addImage(pb);  
  213.         if (camera != null) {  
  214.             camera.stopPreview();  
  215.             camera.startPreview();  
  216.             // 自动对焦  
  217.             camera.autoFocus(null);  
  218.             isPreview = true;  
  219.         }  
  220.     }  
  221.     /**  
  222.      * 旋转相机和设置预览大小  
  223.      * @param parameters  
  224.      */  
  225.     public void resetCameraSize(Parameters parameters){  
  226.         if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {  
  227.             // 如果是竖屏  
  228.             camera.setDisplayOrientation(90);  
  229.         } else {  
  230.             camera.setDisplayOrientation(0);  
  231.         }  
  232.         width = display.getWidth();  
  233.         height = display.getHeight();  
  234.   
  235.         // 设置预览的大小  
  236.         parameters.setPreviewSize(width, height);  
  237.         // 设置照片大小  
  238.         parameters.setPictureSize(width, height);  
  239.     }  
  240. //  @Override  
  241. //  protected void onDestroy() {  
  242. //      super.onDestroy();  
  243. //      ImageUtils.clearImageFile(pictureBeanList);  
  244. //  }  
  245. }  

第二种方式,通过实现Camera.PreviewCallback接口,重写public void onPreviewFrame(byte[] data, Camera camera) { }方法。当相机正在预览的时候,按下拍照按钮,取出预览那一张图像,相当于截取预览区域的图像。注意这里面的byte[] data不能直接转换成Bitmap,否则会出现空指针异常,而且图片的大小事0B。只有通过Android提供的YuvImage类来压缩成图片。我这里进行了把照片宽高按照4:3的比例来计算。当然,这里获得的Size对象,各个手机的宽高都不一致,但是他们取出来的照片尺寸都很大。符合项目要求。

@Override

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public void onPreviewFrame(byte[] data, Camera camera) {  
  2.     mByte = data;  
  3. }  
  4.   
  5. ate void saveBitmap(){  
  6.     try {  
  7.         Camera.Parameters parameters = mCamera.getParameters();  
  8.         Size size = parameters.getPreviewSize();  
  9.         YuvImage image = new YuvImage(mByte, parameters.getPreviewFormat(),  
  10.                 size.width, size.height, null);  
  11.         File file = new File(Util.PHOTO_TEMP);  
  12.         FileOutputStream filecon = new FileOutputStream(file);  
  13.         //按4:3来缩放图片  
  14.         int width = image.getWidth();  
  15.         int height = image.getHeight();  
  16.         int iWidth;  
  17.         int iHeigth;  
  18.         iHeigth = (width*3)/4;  
  19.         if(iHeigth>=height){  
  20.             iHeigth = height;  
  21.             iWidth = (height*4)/3;  
  22.         }else{  
  23.             iWidth = width;  
  24.         }  
  25.         image.compressToJpeg(  
  26.                 new Rect(0, 0, iWidth, iHeigth), 100,  
  27.                 filecon);  
  28.     } catch (Exception e) {  
  29.   
  30.     }  
  31. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值