Android 图片裁切框架 uCrop 的用法
来源:互联网 发布:化学发展史 知乎 编辑:程序博客网 时间:2024/06/05 07:05
1 uCrop简介
最近项目中用到了图片裁剪功能,于是百度了一下,发现了uCrop这个框架,这个框架的星星数很多,就决定使用这个框架
uCrop的Github地址:https://github.com/Yalantis/uCrop
uCrop的特点:
- 裁剪框不动,图片动
- 图片可以旋转,缩放
- 支持各种比例裁剪框
uCrop的效果图(来自其Github):
2 集成uCrop
(1) uCrop集成方法:
compile 'com.yalantis:ucrop:1.4.1'
(2) 修改当前项目的build.gradle文件,修改后代码如下:
android { compileSdkVersion 23 buildToolsVersion "23.0.2" defaultConfig { applicationId "com.test" minSdkVersion 15 targetSdkVersion 23 versionCode 1 versionName "1.0" } ....}dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:appcompat-v7:23.3.0' compile 'com.yalantis:ucrop:1.4.1'}
注意:修改了targetSdkVersion后com.android.support:appcompat-v7的版本也要相匹配
虽然使用maven依赖的话即使appcompat-v7的版本不匹配也没有关系,但使用aar文件则会报错,所以建议你修改了compileSdkVersion 后也要修改appcompat-v7的版本,搞不好就会遇到问题
(3) 如果你没有23版本的sdk,也就是Android 6.0的sdk,则要启动sdk manger去下载,同时也要下载Android SDK Build-tools 23.0.2,如下图:
(4) 修改gradle插件的版本
修改整个project最外面的全局build.gradle文件的gradle版本:
dependencies { classpath 'com.android.tools.build:gradle:2.0.0' }
(5) 下载最新的gradle
Gradle下载地址:http://services.gradle.org/distributions
目前最新版本是gradle-2.13-rc-2-all.zip,下载完成后解压,然后在Android Studio中指定gradle的地址,如下图所示:
要使用2.0以上版本的gradle插件,必须使用2.10以上的gradle,注意gradle插件和gradle是两个东西,前者是Android Studio的插件,后者是独立的东西
(6) 准备工作完毕,同步代码,uCrop已经集成到我们的项目中去了,是不是很麻烦?不然我写这篇文章干嘛。
注意:uCrop必须使用23及以上版本的sdk,gradle插件版本必须2.0.0及以上,gradle版本必须2.10及以上,appcompat-v7版本必须23.0及以上
如果以上都满足了,应该就不会报错了。至于为什么非要23以上的sdk,因为uCrop使用了Android 6.0的新特性:VectorDrawable
3 uCrop的用法
(1) 在AndroidManifest.xml中添加UCropActivity,代码如下:
<activity android:name="com.yalantis.ucrop.UCropActivity" android:screenOrientation="portrait" android:theme="@style/Theme.AppCompat.Light.NoActionBar"/>
(2) 在AndroidManifest.xml中添加权限:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/><uses-permission android:name="android.permission.INTERNET"/>
(3) MainActivity代码如下:
public class MainActivity extends Activity { Button btnTest; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btnTest = (Button) findViewById(R.id.btn_test); btnTest.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startCrop(); } }); } private void startCrop() { Uri sourceUri = Uri.parse("http://star.xiziwang.net/uploads/allimg/140512/19_140512150412_1.jpg"); //裁剪后保存到文件中 Uri destinationUri = Uri.fromFile(new File(getCacheDir(), "SampleCropImage.jpeg")); UCrop.of(sourceUri, destinationUri).withAspectRatio(16, 9).withMaxResultSize(300, 300).start(this); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK) { //裁切成功 if (requestCode == UCrop.REQUEST_CROP) { Uri croppedFileUri = UCrop.getOutput(data); //获取默认的下载目录 String downloadsDirectoryPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath(); String filename = String.format("%d_%s", Calendar.getInstance().getTimeInMillis(), croppedFileUri.getLastPathSegment()); File saveFile = new File(downloadsDirectoryPath, filename); //保存下载的图片 FileInputStream inStream = null; FileOutputStream outStream = null; FileChannel inChannel = null; FileChannel outChannel = null; try { inStream = new FileInputStream(new File(croppedFileUri.getPath())); outStream = new FileOutputStream(saveFile); inChannel = inStream.getChannel(); outChannel = outStream.getChannel(); inChannel.transferTo(0, inChannel.size(), outChannel); Toast.makeText(this, "裁切后的图片保存在:" + saveFile.getAbsolutePath(), Toast.LENGTH_SHORT).show(); } catch (Exception e) { e.printStackTrace(); } finally { try { outChannel.close(); outStream.close(); inChannel.close(); inStream.close(); } catch (Exception e) { e.printStackTrace(); } } } } //裁切失败 if (resultCode == UCrop.RESULT_ERROR) { Toast.makeText(this, "裁切图片失败", Toast.LENGTH_SHORT).show(); } }}
主界面layout\activity_main.xml上就一个按钮,不贴出代码了
(4) 调用uCrop去裁切的方法
Uri sourceUri = Uri.parse("http://star.xiziwang.net/uploads/allimg/140512/19_140512150412_1.jpg"); //裁剪后保存到文件中 Uri destinationUri = Uri.fromFile(new File(getCacheDir(), "SampleCropImage.jpeg")); UCrop.of(sourceUri, destinationUri).withAspectRatio(16, 9).withMaxResultSize(300, 300).start(this);
本例中是从网上下载一张图片,裁切后保存到本地
(5) 获取裁切后的图片代码如下
//裁切成功if (requestCode == UCrop.REQUEST_CROP) { Uri croppedFileUri = UCrop.getOutput(data); //获取默认的下载目录 String downloadsDirectoryPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath(); String filename = String.format("%d_%s", Calendar.getInstance().getTimeInMillis(), croppedFileUri.getLastPathSegment()); File saveFile = new File(downloadsDirectoryPath, filename); //保存下载的图片 FileInputStream inStream = null; FileOutputStream outStream = null; FileChannel inChannel = null; FileChannel outChannel = null; try { inStream = new FileInputStream(new File(croppedFileUri.getPath())); outStream = new FileOutputStream(saveFile); inChannel = inStream.getChannel(); outChannel = outStream.getChannel(); inChannel.transferTo(0, inChannel.size(), outChannel); Toast.makeText(this, "裁切后的图片保存在:" + saveFile.getAbsolutePath(), Toast.LENGTH_SHORT).show(); } catch (Exception e) { e.printStackTrace(); } finally { try { outChannel.close(); outStream.close(); inChannel.close(); inStream.close(); } catch (Exception e) { e.printStackTrace(); } } }
重写onActivityResult()方法,通过data获取返回的uri,再从uri中取得裁切后的文件地址,然后保存到本地
注意:要获取裁切后的uri,必须使用 Uri croppedFileUri = UCrop.getOutput(data)
,不能使用 Uri uri = data.getData()
否则会报空指针错误
如果裁切失败,代码如下:
//裁切失败 if (resultCode == UCrop.RESULT_ERROR) { Toast.makeText(this, "裁切图片失败", Toast.LENGTH_SHORT).show(); }
4 效果图
5 使用aar遇到的问题
为什么建议使用aar文件,而不是maven依赖,请参考我的这篇博客:
[Android Studio系列(三)]Android Studio 编译、同步慢的解决方法
如何下载uCrop的aar文件也请参考我上面这篇博客,目前下载的最新的uCrop的aar文件是ucrop-1.4.1.aar
如果使用uCrop的aar文件的话,可能会遇到下面的问题:
仔细看报的错:
Error:(35) No resource identifier found for attribute 'srcCompat' in package 'com.test3'
百度了半天,也没有找到原因,最后模仿uCrop的demo修改了appcompat-v7的版本,解决了问题,经过实践,appcompat-v7应该修改为如下代码:
compile 'com.android.support:appcompat-v7:23.3.0'
6 其他可能遇到的问题
(1) sdk版本太低
仔细看,发现报下面两个错:
Error:(2) Error retrieving parent for item: No resource found that matches the given name ‘android:TextAppearance.Material.Widget.Button.Inverse’.
Error:(2) Error retrieving parent for item: No resource found that matches the given name ‘android:Widget.Material.Button.Colored’.
报这两个错的原因是: values-23是API 23(Android 6.0)中的资源文件,也就是说我们的sdk版本太低了。查看uCrop给出的例子发现确实是我们的版本太低了, uCrop的示例中build.gradle文件地址如下:
https://github.com/Yalantis/uCrop/blob/master/sample/build.gradle
(2) gradle插件版本太低
仔细看,报错:
Caused by: org.xmlpull.v1.XmlPullParserException: Binary XML file line #1: invalid drawable tag vector
at android.graphics.drawable.Drawable.createFromXmlInner(Drawable.java:933)
如果sdk已经是23了,运行时报下面的错,就是gradle插件版本没有达到2.0的原因,解决方法是:classpath 'com.android.tools.build:gradle:2.0.0'
(3) gradle版本太低
仔细看,报错:
Error:Gradle version 2.10 is required. Current version is 2.8. If using the gradle wrapper, try editing the distributionUrl in D:\AndroidStudioProjects\Hello7\gradle\wrapper\gradle-wrapper.properties to gradle-2.10-all.zip
Fix Gradle wrapper and re-import project
Gradle settings
一看就明白是gradle版本太低了,按照第2步去下载最新的gradle,然后在Android Studio中指定即可
(4) 引入UCropActivity不当导致action bar报错
仔细看,报错:
Caused by: java.lang.IllegalStateException: This Activity already has an action bar supplied by the window decor. Do not request Window.FEATURE_SUPPORT_ACTION_BAR and set windowActionBar to false in your theme to use a Toolbar instead.
原因是,在AndroidManifest.xml中UCropActivity时掉了android:theme="@style/Theme.AppCompat.Light.NoActionBar"
这句话,正确的引入代码是:
<activity android:name="com.yalantis.ucrop.UCropActivity" android:screenOrientation="portrait" android:theme="@style/Theme.AppCompat.Light.NoActionBar"/>
注意:最后一句不能掉
(5) Mutate() is not supported for older platform 问题
最近在使用的时候发现报了下面这个错误:
仔细看报错:
Mutate() is not supported for older platform - Therefore, override color resource (ucrop_color_toolbar_widget) in your app to make it work on pre-L devices
解决方法是在color.xml中添加下面一段代码:
<!-- UCrop colors --><color name="ucrop_color_toolbar_widget">@color/white</color>
如果还是无法显示图片,那么请检查你的图片url是否能正确打开。
7 总结
经过一番折腾,终于把uCrop用上了,这个项目还是很新的,使用了Android 6.0中的victor drawable,代码中也用到很多Android新特性,例如:注释@NoNull等,值得去看一看作者的源码。经过本文的讲解,相信你应该已经愉快的用上了uCrop了,如果还遇到什么问题,欢迎给我留言
8 转载请注明来自”梧桐那时雨”的博客:http://blog.csdn.net/fuchaosz/article/details/51202264
Tips
如果觉得这篇博客对你有帮助或者喜欢博主的写作风格,就给博主留个言或者顶一下呗,鼓励博主创作出更多优质博客,Thank you.
- Android 图片裁切框架 uCrop 的用法
- Android 图片剪切框架 uCrop 简单集成
- 图片裁剪框架ucrop使用前的封装
- Android图片剪裁库:uCrop
- Android 图片剪切 UCrop 使用过程中的坑
- 对图片裁剪框架 ucrop 的二次封装的工具类,添加从图库选择和拍照获取图片,项目中可直接使用,十分便捷
- Android强大的图片加载框架:Glide的基本用法
- Android强大的图片加载框架Fresco简单用法
- Android图片加载框架Glide的基本用法
- Android图片加载框架-Glide的基本用法
- Android图片加载框架 Glide 的基本用法
- Android图片加载框架,Glide的简单用法
- Android图片加载框架Glide的基本用法详解
- Android图片加载框架Glide的简单用法
- uCrop图片裁剪开源库使用总结
- UCrop:图片裁剪开源库详细使用
- 基于ucrop实现图片裁剪需求
- Android图片加载框架Glide用法
- 图片动态效果
- c
- web 前端,on的使用
- 八数码之 ①暴力BFS+哈希表版 ②双向BFS+输出最佳方案版
- MFC 多语言环境的实现
- Android 图片裁切框架 uCrop 的用法
- aspx 上传文件大小
- CodeForces 615E Hexagons
- c
- DOM操作为什么慢?
- netty5源码探索(一)----ByteBuf初探
- java mysql 数据类型对照
- 关于Tomcat 6的热部署和热加载
- Timeline Maker Pro 3.1.99 最新版 中文 汉化版 最好的 时间线 图表制作工具