安卓拍照,选取照片并裁减完全解决方案

拍照几乎是现在APP必备的一项功能,十分基础,如果按照原生SDK进行编程的话,是很简单的,网上教程一大把,但是国内很多系统定制,最常见的有小米,华为国外的索尼。这些系统对原生系统的更改没有统一的标准,这样,你写的一套程序在小米上运行通过,但是在华为上就不行,在华为上面通过在索尼上面跑不了,话说,对于兼容性这种坑我已经踩过很多次了。苦不堪言。言归正传,接下来就说拍照吧。

裁减的两种方式:

不管哪种方式,首先调用系统相机,打开系统相机,获取到系统相机拍照后的图片。这一步很容易做,然后将图片的URI传递给系统裁剪程序进行裁剪,裁剪之后按照需要会有两种方式返回裁剪后的图片:

1,通过Parcelabel将图片传过来,这种方式是很常用的,即使这种方法很笨重,接下来会说为什么常用。

2,获取裁减后图片的URI。在安卓里面,有URI就相当于有一个文件,将此URL转化为文件路径,然后使用图片加载框架(推荐)将图片绑定到相应的控件或者上传图片文件(一般需要裁剪)。这种方式很好的解决OOM的问题,并且很轻量,不用在程序中把图片传来传去,并且响应速度非常好。

在我找到第二种方式之后,就以为拍照就这么完了,蛋疼的事还在后面,突然有一天,运营告诉我,用户的华为P6不能设置头像,在用同事的手机连上电脑,执行拍照程序发现,确实不能设置头像,这件事纠结了半天的的时间,毫无头绪,最后只能硬着头皮看系统log,重试了几次后发现,华为P6手机在运行我得第二种拍照方式的时候,会报一个华为自定义的异常,并且还是系统底层的,很难发现,开头是:HWxxxxException..知道原因了,华为在裁减上面动了手脚,导致不能使用第二种方式来传递图片。只能改程序了,通过第一种方式就是将图片传进程序。

经过测试发现,这段程序在华为和手上的测试机都能通过,知道同事用他的索尼测试,裁剪之后程序崩溃,只有将索尼手机接入IDE,,索尼的日志还是很好找的,也很直接,报错为:ParcelabelTooLargeException,查询手机参数后发现,索尼手机像素惊为1300W。即使经过裁减,还是很大。当时还是挺崩溃的,这期间我看了像QQ,脉脉手机上几乎大部分应用的拍照裁减功能,发现它们有两共性:1,自己写裁减程序,这种门槛较高 2,裁减后的图片很小,基本上是100X100的小图,受到启发,在裁减之前先把图片缩减。包括缩小图片大小已满足手机屏幕和对照片品质进行衰减。经过反复测试,将照片按照屏幕裁减,然后品质衰减30%在手上的所有手机上都能运行通过。但是相片品质不是太好,但是也能满足要求。说了这么多,接下来贴关键代码吧:

public void cropPicture(Activity activity, Uri uri,int aspectX,int aspectY,int outputX,int outputY) {Intent innerIntent = new Intent("com.android.camera.action.CROP");innerIntent.setDataAndType(uri, "image/*");innerIntent.putExtra("crop", "true");// 才能出剪辑的小方框,不然没有剪辑功能,只能选取图片innerIntent.putExtra("aspectX", aspectX); // 放大缩小比例的XinnerIntent.putExtra("aspectY", aspectY);// 放大缩小比例的X 这里的比例为: 1:1innerIntent.putExtra("outputX", outputX); //这个是限制输出图片大小innerIntent.putExtra("outputY", outputY); innerIntent.putExtra("return-data",true);innerIntent.putExtra("scale", true);activity.startActivityForResult(innerIntent, Constants.REUQESTCODE_CROP_PICTURE);}其中,至于衰减代码,原理就是 将拍照得到的图片URI,通过文件写入到本地,通过BitmapFacotory这个类来进行衰减,代码如下:private File saveBitmapToLocal(Bitmap bitmap) {if(bitmap!=null){String fileName=fileUtils.getTempFileName()+".jpg";File file =new File(fileUtils.getStoragePath(),fileName);if(!file.exists()){try {file.createNewFile();} catch (IOException e) {e.printStackTrace();}}try {BufferedOutputStream bos= new BufferedOutputStream(new FileOutputStream(file));bitmap.compress(Bitmap.CompressFormat.JPEG, 70, bos);bos.flush();bos.close();bitmap.recycle();return file;} catch (Exception e) {e.printStackTrace();ToastUtil.show("写入文件失败,请重试");if(bitmap!=null){bitmap.recycle();}return null;}}else{return null;}}

版权声明:本文为博主原创文章,未经博主允许不得转载。

学习会使你永远立于不败之地。

安卓拍照,选取照片并裁减完全解决方案

相关文章:

你感兴趣的文章:

标签云: