android 自定义相机拍照的两种方式
2014-05-16 21:10
399 查看
第一种方式,通过按拍照键实现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) { } }
相关文章推荐
- android 自定义相机拍照的两种方式
- Android-打开系统相机并拍照两种显示方式。
- Android调用系统相机拍照并保存到SD卡的两种实现方式
- 【Android 开发】SufaceView自定义相机拍照
- Android自定义相机实现拍照、预览、显示、上传
- java4Android(12)java中的异常(13)自定义异常,异常处理的两种方式
- Android自定义相机拍照、图片裁剪的实现
- Android中自定义Dialog常用的两种方式
- android关于三星手机自定义相机拍照后照片旋转90度解决方案
- Android—实现自定义相机倒计时拍照
- android 自定义用相机拍照后的照片存储位置
- Android调用系统相机拍照及图片保存的Uri方式------菜鸟学习历程
- Android中自定义Dialog常用的两种方式
- Android自定义button点击效果的两种方式
- android 自定义比例裁剪图片(拍照 相册)方式 自定义比例
- Android中自定义Dialog布局的两种方式比较
- android 自定义radiogroup的两种方式
- android中广播的两种启动方式浅析【自定义Action】
- android自定义相机、连续(自动)聚焦、点击(触摸)聚焦、变焦、拍照后自定义裁剪、旋转
- 【Android】自定义相机的实现(支持连续拍照、前后摄像头切换、连续对焦)