Introduction to Glide, Image Loader Library for Android, recommended by Google

In the passed Google Developer Summit Thailand, Google introduced us an Image Loader Library for Android developed by bumptech named Glide as a library that recommended by Google. It has been used in many Google open source projects till now including Google I/O 2014 official application. It succeeded in making me interested. I spent a whole night playing with it and decided to share my experience in this blog post. As a begining, I must say that it looks 90% similar to Picasso. To be more precise, I think it is something like a Picasso-clone. ...

2015年11月6日 · 12 分钟 · 天边的星星

Android5.0+(CoordinatorLayout)

英文原文:https://guides.codepath.com/android/Handling-Scrolls-with-CoordinatorLayout 这篇文章专门讲解和CoordinatorLayout相关的知识点,这也是Design Support Library中最重要与最难的部分。 概览 CoordinatorLayout 实现了多种Material Design中提到的滚动效果。目前这个框架提供了几种不用写动画代码就能工作的方法,这些效果包括: 让浮动操作按钮上下滑动,为Snackbar留出空间。 扩展或者缩小Toolbar或者头部,让主内容区域有更多的空间。 控制哪个view应该扩展还是收缩,以及其显示大小比例,包括视差滚动效果动画。 设置 首先确保遵循了Design Support Library的使用说明。 浮动操作按钮与Snackbar CoordinatorLayout可以用来配合浮动操作按钮的 layout_anchor 和 layout_gravity属性创造出浮动效果,详情请参见浮动操作按钮指南。 当Snackbar在显示的时候,往往出现在屏幕的底部。为了给Snackbar留出空间,浮动操作按钮需要向上移动。 只要使用CoordinatorLayout作为基本布局,将自动产生向上移动的动画。浮动操作按钮有一个 默认的 behavior来检测Snackbar的添加并让按钮在Snackbar之上呈现上移与Snackbar等高的动画。 [?](http://my.oschina.net/kooeasy/blog/484593#) <table border="0" cellspacing="0" cellpadding="0"> <tr> <td class="gutter"> <div class="line number1 index0 alt2"> 1 </div> <div class="line number2 index1 alt1"> 2 </div> <div class="line number3 index2 alt2"> 3 </div> <div class="line number4 index3 alt1"> 4 </div> <div class="line number5 index4 alt2"> 5 </div> <div class="line number6 index5 alt1"> 6 </div> <div class="line number7 index6 alt2"> 7 </div> <div class="line number8 index7 alt1"> 8 </div> <div class="line number9 index8 alt2"> 9 </div> <div class="line number10 index9 alt1"> 10 </div> <div class="line number11 index10 alt2"> 11 </div> <div class="line number12 index11 alt1"> 12 </div> <div class="line number13 index12 alt2"> 13 </div> <div class="line number14 index13 alt1"> 14 </div> <div class="line number15 index14 alt2"> 15 </div> <div class="line number16 index15 alt1"> 16 </div> <div class="line number17 index16 alt2"> 17 </div> <div class="line number18 index17 alt1"> 18 </div> <div class="line number19 index18 alt2"> 19 </div> <div class="line number20 index19 alt1"> 20 </div> <div class="line number21 index20 alt2"> 21 </div> <div class="line number22 index21 alt1"> 22 </div> </td> <td class="code"> <div class="container"> <div class="line number1 index0 alt2"> ` ``&lt;``android.support.design.widget.CoordinatorLayout` </div> <div class="line number2 index1 alt1"> ` ``android:id``=``"@+id/main_content"` </div> <div class="line number3 index2 alt2"> ` ``xmlns:android``=``"http://schemas.android.com/apk/res/android"` </div> <div class="line number4 index3 alt1"> ` ``xmlns:app``=``"http://schemas.android.com/apk/res-auto"` </div> <div class="line number5 index4 alt2"> ` ``android:layout_width``=``"match_parent"` </div> <div class="line number6 index5 alt1"> ` ``android:layout_height``=``"match_parent"``&gt;` </div> <div class="line number7 index6 alt2"> ` ` </div> <div class="line number8 index7 alt1"> ` ``&lt;``android.support.v7.widget.RecyclerView` </div> <div class="line number9 index8 alt2"> ` ``android:id``=``"@+id/rvToDoList"` </div> <div class="line number10 index9 alt1"> ` ``android:layout_width``=``"match_parent"` </div> <div class="line number11 index10 alt2"> ` ``android:layout_height``=``"match_parent"``&gt;` </div> <div class="line number12 index11 alt1"> ` ``&lt;/``android.support.v7.widget.RecyclerView``&gt;` </div> <div class="line number13 index12 alt2"> ` ` </div> <div class="line number14 index13 alt1"> ` ``&lt;``android.support.design.widget.FloatingActionButton` </div> <div class="line number15 index14 alt2"> ` ``android:layout_width``=``"wrap_content"` </div> <div class="line number16 index15 alt1"> ` ``android:layout_height``=``"wrap_content"` </div> <div class="line number17 index16 alt2"> ` ``android:layout_gravity``=``"bottom|right"` </div> <div class="line number18 index17 alt1"> ` ``android:layout_margin``=``"16dp"` </div> <div class="line number19 index18 alt2"> ` ``android:src``=``"@mipmap/ic_launcher"` </div> <div class="line number20 index19 alt1"> ` ``app:layout_anchor``=``"@id/rvToDoList"` </div> <div class="line number21 index20 alt2"> ` ``app:layout_anchorGravity``=``"bottom|right|end"``/&gt;` </div> <div class="line number22 index21 alt1"> ` ``&lt;/``android.support.design.widget.CoordinatorLayout``&gt;` </div> </div> </td> </tr> </table> </div> Toolbar的扩展与收缩 首先需要确保你不是使用已经过时的ActionBar。务必遵循 使用ToolBar作为actionbar这篇文章的指南。同样,这里也需要CoordinatorLayout作为主布局容器。 ...

2015年11月5日 · 11 分钟 · 天边的星星

Universal-Image-Loader,android-Volley,Picasso、Fresco和Glide五大Android开源组件加载网络图片的优缺点比较

在android中的加载网络图片是一件十分令人头疼的事情,在网上有着许多关于加载网络图片的开源库,可以让我们十分方便的加载网络图片。在这里我主要介绍一下我自己在使用Volley, Picasso, Universal-Imageloader的一些使用的感悟。以及最基本的用法介绍。 1.android-Volley 给ImageView设置图片源 - > // imageView是一个ImageView实例 - > // ImageLoader.getImageListener的第二个参数是默认的图片resource id - > // 第三个参数是请求失败时候的资源id,可以指定为0 - > ImageListener listener = ImageLoader.getImageListener(imageView, android.R.drawable.ic_menu_rotate, android.R.drawable.ic_delete); - > mImageLoader.get(url, listener); 复制代码 使用NetworkImageView Volley提供了一个新的控件NetworkImageView来代替传统的ImageView,这个控件的图片属性可以通过 - > mImageView.setImageUrl(url, imageLoader) 复制代码 来设定。而且,这个控件在被从父控件detach的时候,会自动取消网络请求的,即完全不用我们担心相关网络请求的生命周期问题。 - > mImageLoader = new ImageLoader(mRequestQueue, new BitmapLruCache()); - > &#8230;. &#8230; - > - > if(holder.imageRequest != null) { - > holder.imageRequest.cancel(); - > } - > holder.imageRequest = mImageLoader.get(BASE_UR + item.image_url, holder.imageView, R.drawable.loading, R.drawable.error); - > 复制代码 总结:如果你的工程项目,是一个比较小的项目,或者要求不是很高的项目,处理比较简单的可以使用这个库,这个库是Google 2013 I/O 发布的一个开源库。使用这个库在图片的处理上,没有提供任何的图片处理的操作,个人感觉这个库主要在网络数据连接上比较好,在图片处理上还是不够完善,强大。 ...

2015年11月5日 · 2 分钟 · 天边的星星

Android库Volley的使用介绍

Android Volley 是Google开发的一个网络lib,可以让你更加简单并且快速的访问网络数据。Volley库的网络请求都是异步的,你不必担心异步处理问题。 Volley的优点: 请求队列和请求优先级 请求Cache和内存管理 扩展性性强 可以取消请求 ##下载和编译volley.jar 需要安装git,ant,android sdk clone代码: git clone https://android.googlesource.com/platform/frameworks/volley 编译jar: android update project -p . ant jar 添加volley.jar到你的项目中 不过已经有人将volley的代码放到github上了: https://github.com/mcxiaoke/android-volley,你可以使用更加简单的方式来使用volley: ###Maven format: jar <span class="tag"><<span class="title">dependency</span>></span> <span class="tag"><<span class="title">groupId</span>></span>com.mcxiaoke.volley<span class="tag"></<span class="title">groupId</span>></span> <span class="tag"><<span class="title">artifactId</span>></span>library<span class="tag"></<span class="title">artifactId</span>></span> <span class="tag"><<span class="title">version</span>></span>1.0.6<span class="tag"></<span class="title">version</span>></span> <span class="tag"></<span class="title">dependency</span>></span> ###Gradle format: jar compile 'com.mcxiaoke.volley:library:1.0.6' ##Volley工作原理图 {.fancybox} ##创建Volley 单例 使用volley时,必须要创建一个请求队列RequestQueue,使用请求队列的最佳方式就是将它做成一个单例,整个app使用这么一个请求队列。 <span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">AppController</span> <span class="keyword">extends</span> <span class="title">Application</span> </span>{ <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">final</span> String TAG = AppController.class .getSimpleName(); <span class="keyword">private</span> RequestQueue mRequestQueue; <span class="keyword">private</span> ImageLoader mImageLoader; <span class="keyword">private</span> <span class="keyword">static</span> AppController mInstance; <span class="annotation">@Override</span> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onCreate</span><span class="params">()</span> </span>{ <span class="keyword">super</span>.onCreate(); mInstance = <span class="keyword">this</span>; } <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">synchronized</span> AppController <span class="title">getInstance</span><span class="params">()</span> </span>{ <span class="keyword">return</span> mInstance; } <span class="function"><span class="keyword">public</span> RequestQueue <span class="title">getRequestQueue</span><span class="params">()</span> </span>{ <span class="keyword">if</span> (mRequestQueue == <span class="keyword">null</span>) { mRequestQueue = Volley.newRequestQueue(getApplicationContext()); } <span class="keyword">return</span> mRequestQueue; } <span class="function"><span class="keyword">public</span> ImageLoader <span class="title">getImageLoader</span><span class="params">()</span> </span>{ getRequestQueue(); <span class="keyword">if</span> (mImageLoader == <span class="keyword">null</span>) { mImageLoader = <span class="keyword">new</span> ImageLoader(<span class="keyword">this</span>.mRequestQueue, <span class="keyword">new</span> LruBitmapCache()); } <span class="keyword">return</span> <span class="keyword">this</span>.mImageLoader; } <span class="keyword">public</span> <T> <span class="function"><span class="keyword">void</span> <span class="title">addToRequestQueue</span><span class="params">(Request<T> req, String tag)</span> </span>{ <span class="comment">// set the default tag if tag is empty</span> req.setTag(TextUtils.isEmpty(tag) ? TAG : tag); getRequestQueue().add(req); } <span class="keyword">public</span> <T> <span class="function"><span class="keyword">void</span> <span class="title">addToRequestQueue</span><span class="params">(Request<T> req)</span> </span>{ req.setTag(TAG); getRequestQueue().add(req); } <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">cancelPendingRequests</span><span class="params">(Object tag)</span> </span>{ <span class="keyword">if</span> (mRequestQueue != <span class="keyword">null</span>) { mRequestQueue.cancelAll(tag); } } } 另外,你还需要一个Cache来存放请求的图片: ...

2015年11月4日 · 6 分钟 · 天边的星星

如何使用Android Studio把自己的Android library分享到jCenter和Maven Central

原文:How to distribute your own Android library through jCenter and Maven Central from Android Studio 如果你想在Android Studio中引入一个library到你的项目,你只需添加如下的一行代码到模块的build.gradle文件中。 1 <div class="line number2 index1 alt1"> 2 </div> <div class="line number3 index2 alt2"> 3 </div> </td> <td class="code"> <div class="container"> <div class="line number1 index0 alt2"> `dependencies {` </div> <div class="line number2 index1 alt1"> ` ``compile ``'com.inthecheesefactory.thecheeselibrary:fb-like:0.9.3'` </div> <div class="line number3 index2 alt2"> `}` </div> </div> </td> </tr> </table> 就是如此简单的一行代码,你就可以使用这个library了。 ...

2015年11月4日 · 9 分钟 · 天边的星星

介绍4款json的java类库 及 其性能测试

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。 易于人阅读和编写。同时也易于机器解析和生成。 它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition – December 1999的一个子集。 JSON采用完全独立于语言的文本格式,这些特性使JSON成为理想的数据交换语言。 下面介绍四款处理json的java类库:Json-lib、Gson、Jackson、Fastjson 一、Json-lib JSON-lib is a java library for transforming beans, maps, collections, java arrays and XML to JSON and back again to beans and DynaBeans. 官网:http://json-lib.sourceforge.net/ maven依赖配置: ![复制代码](http://common.cnblogs.com/images/copycode.gif) &lt;dependency&gt; &lt;groupId&gt;net.sf.json-lib&lt;/groupId&gt; &lt;artifactId&gt;json-lib&lt;/artifactId&gt; &lt;version&gt;2.4&lt;/version&gt; &lt;classifier&gt;jdk15&lt;/classifier&gt; &lt;/dependency&gt; ![复制代码](http://common.cnblogs.com/images/copycode.gif) 示例: ![复制代码](http://common.cnblogs.com/images/copycode.gif) /** * 将对象序列化成json字符串 * @param obj * @return */ public static String bean2Json(Object obj){ JSONObject jsonObject=JSONObject.fromObject(obj); return jsonObject.toString(); } /** * 将json字符串反序列化为对象 * @param jsonStr * @param objClass 反序列化为该类的对象 * @return */ @SuppressWarnings("unchecked") public static &lt;T&gt; T json2Bean(String jsonStr,Class&lt;T&gt; objClass){ return (T)JSONObject.toBean(JSONObject.fromObject(jsonStr), objClass); } ![复制代码](http://common.cnblogs.com/images/copycode.gif) ...

2015年11月4日 · 5 分钟 · 天边的星星

Android开源库

在摸索过程中,GitHub上搜集了很多很棒的Android第三方库,推荐给在苦苦寻找的开发者,而且我会不定期的更新这篇文章。 Android下的优秀开发库数不胜数,在本文中,我列举的多是开发流程中最常用的一些。如果你还想了解更多的Android开源库,可以查看我的GitHub Star,过滤Java选项,每一个库都是我认真查看或者编译运行的,希望对你产生帮助。 一、兼容类库 ActionBarSherlock : Action Bar是Android 3.0后才开始支持的,ActionBarSherlock是让Action Bar功能支持2.X后的所有平台,而且他会自动的判断是调用原生Action Bar还是使用扩展ActionBar。在我的小熊词典里有用到这个库,而且很多非常知名的App也在使用这个库。GitHub Official ActionBar科普 最新消息(2013年7月):Android官方发布的的Support Library Revision 18 开始支持ActionBar的兼容。所以可以不用再使用ActionBarSherlock了。 Android-ViewPagerIndicator : 这是与ViewPager兼容的一个分页指示器库。分页指示器(Friends 和 Suggested就是分页,而下面蓝色的小条就是指示器,ViewPagerIndicator支持多种样式的指示器。):GitHub NineOldAndroids : NineOldAndroids 将 Honeycomb (Android 3.0) 的动画 API扩展到了Android 1.0以上。这个库的作者即是ActionBarSherlock的作者,也是Android-ViewPagerIndicator的作者,Jake Wharton, 非常厉害的一个人,Github关注量超过1.6K,如果你也做Android开发或者即将开始学习Android开发,一定要去Follow他,而且留意一下他每次的star和follow信息,经常会有很惊奇的发现。 HoloEverywhere:在Android 4.0时,Google引入了新的主题风格—Holo,多数厂商都想统一界面设计UI,因此更加具有兼容性的Holo主题库HoloEveryWhere便成为很多开发者的选择。在Android的官方Blog中也对HoloEveryWhere这个库有所推荐,点此查看官方博客对HoloEveryWhere的介绍。HoloEveryWhere的Github。 Android-Datepicker: 兼容Android 4.0的datepicker至Android 2.2。 GitHub **二、**扩展功能库 SlidingMenu : SlidingMenu 能非常容易的让开发者实现程序的抽屉效果,所谓的抽屉效果如下图所示,通常被用作呼出菜单。而且SlidingMenu能很方便的与ActionBarSherlock融合,在官方GitHub上有关于如何融合的说明。 GitHub 同时,想要达到相同功能也可以看另一个Drawer设计:Android-Undergarment AppMsg : 优雅的弹出类似Toast的消息提示,支持3种状态Alert,Confirm以及Info。GitHub Drag-Sort-ListView : 很多人都用过在一个ListView中通过拖拽对已有的数据进行排序操作。Drag-Sort-Listview就是实现这一功能的开源库。GitHub Android-Flip : 轻松实现类似FlipBoard的翻页功能。 GitHub Android-PullToRefresh : Android下拉刷新组件。 GitHub 此外,该作者还有另外一个实用度和关注量极高的项目–另一种Android ActionBar的实现:GitHub 另:GitHub上另一个Android-PullToRefresh的实现。GitHub ActionBar-PullToRefresh: 基于ActionBar的下拉刷新组件,在下拉的时候会替换掉ActionBar,显示更新中… GitHub Demo下载 picasso: 程序中经常面临加载网络图片的情况,成熟做法:异步下载->缓存->显示,Picasso一行代码就可这三步轻松完成。GitHub GitHubPage ,GitHub上图片异步加载缓存类库很多,你也可尝试使用Android-Universal-Image-Loader 或者 LazyList 后面将介绍到的afinal(国人项目)也具有此功能。 Card-UI: Google很早之前开始在自家的App内使用卡片式布局,CardUI极其美观大方,想要在自己的App中集成卡片UI布局,那么就轻松地用这个项目吧。GitHub 或者你也可以使用这个库来完成卡片布局。CardLib 另一个卡片式布局: GitHub ...

2015年11月4日 · 3 分钟 · 天边的星星

android代码运行cmd命令截屏

**adb** shell /system/bin/screencap -p /sdcard/screenshot.png(保存到SDCard) **adb** pull /sdcard/screenshot.png d:/screenshot.png(保存到电脑) <div> </div> <div> </div> <div> <div> `$ adb shell screencap -p /sdcard/screen.png&lt;br /> $ adb pull /sdcard/screen.png<br /> $ adb shell rm /sdcard/screen.png` <div> </div> <div> ## [](https://github.com/bxiaopeng/wirelessqa/blob/master/Android/AndroidTest/Android%E6%88%AA%E5%9B%BE%E5%91%BD%E4%BB%A4screencap.md#%E6%88%AA%E5%9B%BE%E7%9B%B4%E6%8E%A5%E4%BF%9D%E5%AD%98%E5%88%B0%E7%94%B5%E8%84%91)截图直接保存到电脑 <div> <div> `$ adb shell screencap -p | sed 's/\r$//' &gt; screen.png` </div> </div> </div> <div> </div> <div> 上一个命令没有成功(mac下) </div> <div> 下面这个命令成功了 </div> <div> <div> `adb shell screencap -p | perl -pe 's/\x0D\x0A/\x0A/g' &gt; screen.png` </div> </div> <div> </div> <div> </div> <div> 执行adb shell 将\n转换\r\n, 因此需要用sed删除多余的\r </div> <div> </div> <div> ## [](https://github.com/bxiaopeng/wirelessqa/blob/master/Android/AndroidTest/Android%E6%88%AA%E5%9B%BE%E5%91%BD%E4%BB%A4screencap.md#%E5%A6%82%E6%9E%9C%E7%9B%B4%E6%8E%A5%E5%BD%93%E5%91%BD%E4%BB%A4%E7%94%A8%E8%BF%98%E5%8F%AF%E4%BB%A5%E7%94%A8-alias-%E5%8C%85%E8%A3%9D%E8%A3%85%E8%B5%B7%E4%BE%86)如果直接当命令用还可以用 alias 包裝装起來: ``` $ alias and-screencap="adb shell screencap -p | sed 's/\r$//'" $ and-screencap &gt; screen.png ...

2015年10月19日 · 2 分钟 · 天边的星星

Android图片高斯模糊的一些方法

# 高斯模糊 - 高斯模糊就是将指定像素变换为其与周边像素加权平均后的值,权重就是高斯分布函数计算出来的值。 一种实现 [点击打开链接](http://my.oschina.net/tonywolf/blog/64896)<-这里是一片关于高斯模糊算法的介绍,我们需要首先根据高斯分布函数计算权重值,为了提高效率我们采用一维高斯分布函数,然后处理图像的时候在横向和纵向进行两次计算得到结果。下面是一种实现 <div class="dp-highlighter bg_java"> <div class="bar"> <div class="tools"> **[java]** [view plain](http://blog.csdn.net/xu_fu/article/details/23131241#)[copy](http://blog.csdn.net/xu_fu/article/details/23131241#)[print](http://blog.csdn.net/xu_fu/article/details/23131241#)[?](http://blog.csdn.net/xu_fu/article/details/23131241#) <div> <embed id="ZeroClipboardMovie_1" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="29" height="15" align="middle" name="ZeroClipboardMovie_1"> </embed> </div> </div> </div> - <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> gaussBlur(<span class="keyword">int</span>[] data, <span class="keyword">int</span> width, <span class="keyword">int</span> height, <span class="keyword">int</span> radius, - <span class="keyword">float</span> sigma) { - - <span class="keyword">float</span> pa = (<span class="keyword">float</span>) (<span class="number">1</span> / (Math.sqrt(<span class="number">2</span> * Math.PI) * sigma)); - <span class="keyword">float</span> pb = &#8211;<span class="number">1</span>.0f / (<span class="number">2</span> * sigma * sigma); - - <span class="comment">// generate the Gauss Matrix</span> - <span class="keyword">float</span>[] gaussMatrix = <span class="keyword">new</span> <span class="keyword">float</span>[radius * <span class="number">2</span> + <span class="number">1</span>]; - <span class="keyword">float</span> gaussSum = 0f; - <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number"></span>, x = -radius; x <= radius; ++x, ++i) { - <span class="keyword">float</span> g = (<span class="keyword">float</span>) (pa * Math.exp(pb * x * x)); - gaussMatrix[i] = g; - gaussSum += g; - } - - <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number"></span>, length = gaussMatrix.length; i < length; ++i) { - gaussMatrix[i] /= gaussSum; - } - - <span class="comment">// x direction</span> - <span class="keyword">for</span> (<span class="keyword">int</span> y = <span class="number"></span>; y < height; ++y) { - <span class="keyword">for</span> (<span class="keyword">int</span> x = <span class="number"></span>; x < width; ++x) { - <span class="keyword">float</span> r = <span class="number"></span>, g = <span class="number"></span>, b = <span class="number"></span>; - gaussSum = <span class="number"></span>; - <span class="keyword">for</span> (<span class="keyword">int</span> j = -radius; j <= radius; ++j) { - <span class="keyword">int</span> k = x + j; - <span class="keyword">if</span> (k >= <span class="number"></span> && k < width) { - <span class="keyword">int</span> index = y * width + k; - <span class="keyword">int</span> color = data[index]; - <span class="keyword">int</span> cr = (color & <span class="number">0x00ff0000</span>) >> <span class="number">16</span>; - <span class="keyword">int</span> cg = (color & <span class="number">0x0000ff00</span>) >> <span class="number">8</span>; - <span class="keyword">int</span> cb = (color & <span class="number">0x000000ff</span>); - - r += cr * gaussMatrix[j + radius]; - g += cg * gaussMatrix[j + radius]; - b += cb * gaussMatrix[j + radius]; - - gaussSum += gaussMatrix[j + radius]; - } - } - - <span class="keyword">int</span> index = y * width + x; - <span class="keyword">int</span> cr = (<span class="keyword">int</span>) (r / gaussSum); - <span class="keyword">int</span> cg = (<span class="keyword">int</span>) (g / gaussSum); - <span class="keyword">int</span> cb = (<span class="keyword">int</span>) (b / gaussSum); - - data[index] = cr << <span class="number">16</span> | cg << <span class="number">8</span> | cb | <span class="number">0xff000000</span>; - } - } - - <span class="comment">// y direction</span> - <span class="keyword">for</span> (<span class="keyword">int</span> x = <span class="number"></span>; x < width; ++x) { - <span class="keyword">for</span> (<span class="keyword">int</span> y = <span class="number"></span>; y < height; ++y) { - <span class="keyword">float</span> r = <span class="number"></span>, g = <span class="number"></span>, b = <span class="number"></span>; - gaussSum = <span class="number"></span>; - <span class="keyword">for</span> (<span class="keyword">int</span> j = -radius; j <= radius; ++j) { - <span class="keyword">int</span> k = y + j; - <span class="keyword">if</span> (k >= <span class="number"></span> && k < height) { - <span class="keyword">int</span> index = k * width + x; - <span class="keyword">int</span> color = data[index]; - <span class="keyword">int</span> cr = (color & <span class="number">0x00ff0000</span>) >> <span class="number">16</span>; - <span class="keyword">int</span> cg = (color & <span class="number">0x0000ff00</span>) >> <span class="number">8</span>; - <span class="keyword">int</span> cb = (color & <span class="number">0x000000ff</span>); - - r += cr * gaussMatrix[j + radius]; - g += cg * gaussMatrix[j + radius]; - b += cb * gaussMatrix[j + radius]; - - gaussSum += gaussMatrix[j + radius]; - } - } - - <span class="keyword">int</span> index = y * width + x; - <span class="keyword">int</span> cr = (<span class="keyword">int</span>) (r / gaussSum); - <span class="keyword">int</span> cg = (<span class="keyword">int</span>) (g / gaussSum); - <span class="keyword">int</span> cb = (<span class="keyword">int</span>) (b / gaussSum); - data[index] = cr << <span class="number">16</span> | cg << <span class="number">8</span> | cb | <span class="number">0xff000000</span>; - } - } - } </div> 实际测试会发现这种计算方式是很耗时间的,而且模糊半径越大,从原理也可以看到计算量是平方增长的,所以计算时间也越长。 ## <a name="t2"></a>RenderScript RenderScript是Android在API 11之后加入的,用于高效的图片处理,包括模糊、混合、矩阵卷积计算等,代码示例如下 <div class="dp-highlighter bg_java"> <div class="bar"> <div class="tools"> **[java]** [view plain](http://blog.csdn.net/xu_fu/article/details/23131241#)[copy](http://blog.csdn.net/xu_fu/article/details/23131241#)[print](http://blog.csdn.net/xu_fu/article/details/23131241#)[?](http://blog.csdn.net/xu_fu/article/details/23131241#) <div> <embed id="ZeroClipboardMovie_2" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="29" height="15" align="middle" name="ZeroClipboardMovie_2"> </embed> </div> </div> </div> - <span class="keyword">public</span> Bitmap blurBitmap(Bitmap bitmap){ - - <span class="comment">//Let&#8217;s create an empty bitmap with the same size of the bitmap we want to blur</span> - Bitmap outBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888); - - <span class="comment">//Instantiate a new Renderscript</span> - RenderScript rs = RenderScript.create(getApplicationContext()); - - <span class="comment">//Create an Intrinsic Blur Script using the Renderscript</span> - ScriptIntrinsicBlur blurScript = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs)); - - <span class="comment">//Create the Allocations (in/out) with the Renderscript and the in/out bitmaps</span> - Allocation allIn = Allocation.createFromBitmap(rs, bitmap); - Allocation allOut = Allocation.createFromBitmap(rs, outBitmap); - - <span class="comment">//Set the radius of the blur</span> - blurScript.setRadius(<span class="number">25</span>.f); - - <span class="comment">//Perform the Renderscript</span> - blurScript.setInput(allIn); - blurScript.forEach(allOut); - - <span class="comment">//Copy the final bitmap created by the out Allocation to the outBitmap</span> - allOut.copyTo(outBitmap); - - <span class="comment">//recycle the original bitmap</span> - bitmap.recycle(); - - <span class="comment">//After finishing everything, we destroy the Renderscript.</span> - rs.destroy(); - - <span class="keyword">return</span> outBitmap; - - - } </div> (示例来源 [https://gist.github.com/Mariuxtheone/903c35b4927c0df18cf8](https://gist.github.com/Mariuxtheone/903c35b4927c0df18cf8)) ## <a name="t3"></a>FastBlur <div> <div class="dp-highlighter bg_java"> <div class="bar"> <div class="tools"> **[java]** [view plain](http://blog.csdn.net/xu_fu/article/details/23131241#)[copy](http://blog.csdn.net/xu_fu/article/details/23131241#)[print](http://blog.csdn.net/xu_fu/article/details/23131241#)[?](http://blog.csdn.net/xu_fu/article/details/23131241#) <div> <embed id="ZeroClipboardMovie_3" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="29" height="15" align="middle" name="ZeroClipboardMovie_3"> </embed> </div> </div> </div> - <span class="keyword">public</span> <span class="keyword">class</span> FastBlur { - - <span class="keyword">public</span> <span class="keyword">static</span> Bitmap doBlur(Bitmap sentBitmap, <span class="keyword">int</span> radius, <span class="keyword">boolean</span> canReuseInBitmap) { - - <span class="comment">// Stack Blur v1.0 from</span> - <span class="comment">// http://www.quasimondo.com/StackBlurForCanvas/StackBlurDemo.html</span> - <span class="comment">//</span> - <span class="comment">// Java Author: Mario Klingemann <mario at quasimondo.com></span> - <span class="comment">// http://incubator.quasimondo.com</span> - <span class="comment">// created Feburary 29, 2004</span> - <span class="comment">// Android port : Yahel Bouaziz <yahel at kayenko.com></span> - <span class="comment">// http://www.kayenko.com</span> - <span class="comment">// ported april 5th, 2012</span> - - <span class="comment">// This is a compromise between Gaussian Blur and Box blur</span> - <span class="comment">// It creates much better looking blurs than Box Blur, but is</span> - <span class="comment">// 7x faster than my Gaussian Blur implementation.</span> - <span class="comment">//</span> - <span class="comment">// I called it Stack Blur because this describes best how this</span> - <span class="comment">// filter works internally: it creates a kind of moving stack</span> - <span class="comment">// of colors whilst scanning through the image. Thereby it</span> - <span class="comment">// just has to add one new block of color to the right side</span> - <span class="comment">// of the stack and remove the leftmost color. The remaining</span> - <span class="comment">// colors on the topmost layer of the stack are either added on</span> - <span class="comment">// or reduced by one, depending on if they are on the right or</span> - <span class="comment">// on the left side of the stack.</span> - <span class="comment">//</span> - <span class="comment">// If you are using this algorithm in your code please add</span> - <span class="comment">// the following line:</span> - <span class="comment">//</span> - <span class="comment">// Stack Blur Algorithm by Mario Klingemann <mario@quasimondo.com></span> - - Bitmap bitmap; - <span class="keyword">if</span> (canReuseInBitmap) { - bitmap = sentBitmap; - } <span class="keyword">else</span> { - bitmap = sentBitmap.copy(sentBitmap.getConfig(), <span class="keyword">true</span>); - } - - <span class="keyword">if</span> (radius < <span class="number">1</span>) { - <span class="keyword">return</span> (<span class="keyword">null</span>); - } - - <span class="keyword">int</span> w = bitmap.getWidth(); - <span class="keyword">int</span> h = bitmap.getHeight(); - - <span class="keyword">int</span>[] pix = <span class="keyword">new</span> <span class="keyword">int</span>[w * h]; - bitmap.getPixels(pix, <span class="number"></span>, w, <span class="number"></span>, <span class="number"></span>, w, h); - - <span class="keyword">int</span> wm = w &#8211; <span class="number">1</span>; - <span class="keyword">int</span> hm = h &#8211; <span class="number">1</span>; - <span class="keyword">int</span> wh = w * h; - <span class="keyword">int</span> div = radius + radius + <span class="number">1</span>; - - <span class="keyword">int</span> r[] = <span class="keyword">new</span> <span class="keyword">int</span>[wh]; - <span class="keyword">int</span> g[] = <span class="keyword">new</span> <span class="keyword">int</span>[wh]; - <span class="keyword">int</span> b[] = <span class="keyword">new</span> <span class="keyword">int</span>[wh]; - <span class="keyword">int</span> rsum, gsum, bsum, x, y, i, p, yp, yi, yw; - <span class="keyword">int</span> vmin[] = <span class="keyword">new</span> <span class="keyword">int</span>[Math.max(w, h)]; - - <span class="keyword">int</span> divsum = (div + <span class="number">1</span>) >> <span class="number">1</span>; - divsum *= divsum; - <span class="keyword">int</span> dv[] = <span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">256</span> * divsum]; - <span class="keyword">for</span> (i = <span class="number"></span>; i < <span class="number">256</span> * divsum; i++) { - dv[i] = (i / divsum); - } - - yw = yi = <span class="number"></span>; - - <span class="keyword">int</span>[][] stack = <span class="keyword">new</span> <span class="keyword">int</span>[div][<span class="number">3</span>]; - <span class="keyword">int</span> stackpointer; - <span class="keyword">int</span> stackstart; - <span class="keyword">int</span>[] sir; - <span class="keyword">int</span> rbs; - <span class="keyword">int</span> r1 = radius + <span class="number">1</span>; - <span class="keyword">int</span> routsum, goutsum, boutsum; - <span class="keyword">int</span> rinsum, ginsum, binsum; - - <span class="keyword">for</span> (y = <span class="number"></span>; y < h; y++) { - rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = <span class="number"></span>; - <span class="keyword">for</span> (i = -radius; i <= radius; i++) { - p = pix[yi + Math.min(wm, Math.max(i, <span class="number"></span>))]; - sir = stack[i + radius]; - sir[<span class="number"></span>] = (p & <span class="number">0xff0000</span>) >> <span class="number">16</span>; - sir[<span class="number">1</span>] = (p & <span class="number">0x00ff00</span>) >> <span class="number">8</span>; - sir[<span class="number">2</span>] = (p & <span class="number">0x0000ff</span>); - rbs = r1 &#8211; Math.abs(i); - rsum += sir[<span class="number"></span>] * rbs; - gsum += sir[<span class="number">1</span>] * rbs; - bsum += sir[<span class="number">2</span>] * rbs; - <span class="keyword">if</span> (i > <span class="number"></span>) { - rinsum += sir[<span class="number"></span>]; - ginsum += sir[<span class="number">1</span>]; - binsum += sir[<span class="number">2</span>]; - } <span class="keyword">else</span> { - routsum += sir[<span class="number"></span>]; - goutsum += sir[<span class="number">1</span>]; - boutsum += sir[<span class="number">2</span>]; - } - } - stackpointer = radius; - - <span class="keyword">for</span> (x = <span class="number"></span>; x < w; x++) { - - r[yi] = dv[rsum]; - g[yi] = dv[gsum]; - b[yi] = dv[bsum]; - - rsum -= routsum; - gsum -= goutsum; - bsum -= boutsum; - - stackstart = stackpointer &#8211; radius + div; - sir = stack[stackstart % div]; - - routsum -= sir[<span class="number"></span>]; - goutsum -= sir[<span class="number">1</span>]; - boutsum -= sir[<span class="number">2</span>]; - - <span class="keyword">if</span> (y == <span class="number"></span>) { - vmin[x] = Math.min(x + radius + <span class="number">1</span>, wm); - } - p = pix[yw + vmin[x]]; - - sir[<span class="number"></span>] = (p & <span class="number">0xff0000</span>) >> <span class="number">16</span>; - sir[<span class="number">1</span>] = (p & <span class="number">0x00ff00</span>) >> <span class="number">8</span>; - sir[<span class="number">2</span>] = (p & <span class="number">0x0000ff</span>); - - rinsum += sir[<span class="number"></span>]; - ginsum += sir[<span class="number">1</span>]; - binsum += sir[<span class="number">2</span>]; - - rsum += rinsum; - gsum += ginsum; - bsum += binsum; - - stackpointer = (stackpointer + <span class="number">1</span>) % div; - sir = stack[(stackpointer) % div]; - - routsum += sir[<span class="number"></span>]; - goutsum += sir[<span class="number">1</span>]; - boutsum += sir[<span class="number">2</span>]; - - rinsum -= sir[<span class="number"></span>]; - ginsum -= sir[<span class="number">1</span>]; - binsum -= sir[<span class="number">2</span>]; - - yi++; - } - yw += w; - } - <span class="keyword">for</span> (x = <span class="number"></span>; x < w; x++) { - rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = <span class="number"></span>; - yp = -radius * w; - <span class="keyword">for</span> (i = -radius; i <= radius; i++) { - yi = Math.max(<span class="number"></span>, yp) + x; - - sir = stack[i + radius]; - - sir[<span class="number"></span>] = r[yi]; - sir[<span class="number">1</span>] = g[yi]; - sir[<span class="number">2</span>] = b[yi]; - - rbs = r1 &#8211; Math.abs(i); - - rsum += r[yi] * rbs; - gsum += g[yi] * rbs; - bsum += b[yi] * rbs; - - <span class="keyword">if</span> (i > <span class="number"></span>) { - rinsum += sir[<span class="number"></span>]; - ginsum += sir[<span class="number">1</span>]; - binsum += sir[<span class="number">2</span>]; - } <span class="keyword">else</span> { - routsum += sir[<span class="number"></span>]; - goutsum += sir[<span class="number">1</span>]; - boutsum += sir[<span class="number">2</span>]; - } - - <span class="keyword">if</span> (i < hm) { - yp += w; - } - } - yi = x; - stackpointer = radius; - <span class="keyword">for</span> (y = <span class="number"></span>; y < h; y++) { - <span class="comment">// Preserve alpha channel: ( 0xff000000 & pix[yi] )</span> - pix[yi] = (<span class="number">0xff000000</span> & pix[yi]) | (dv[rsum] << <span class="number">16</span>) | (dv[gsum] << <span class="number">8</span>) | dv[bsum]; - - rsum -= routsum; - gsum -= goutsum; - bsum -= boutsum; - - stackstart = stackpointer &#8211; radius + div; - sir = stack[stackstart % div]; - - routsum -= sir[<span class="number"></span>]; - goutsum -= sir[<span class="number">1</span>]; - boutsum -= sir[<span class="number">2</span>]; - - <span class="keyword">if</span> (x == <span class="number"></span>) { - vmin[y] = Math.min(y + r1, hm) * w; - } - p = x + vmin[y]; </div> </div> - sir[<span class="number"></span>] = r[p]; - sir[<span class="number">1</span>] = g[p]; - sir[<span class="number">2</span>] = b[p]; - - rinsum += sir[<span class="number"></span>]; - ginsum += sir[<span class="number">1</span>]; - binsum += sir[<span class="number">2</span>]; - - rsum += rinsum; - gsum += ginsum; - bsum += binsum; - - stackpointer = (stackpointer + <span class="number">1</span>) % div; - sir = stack[stackpointer]; - - routsum += sir[<span class="number"></span>]; - goutsum += sir[<span class="number">1</span>]; - boutsum += sir[<span class="number">2</span>]; - - rinsum -= sir[<span class="number"></span>]; - ginsum -= sir[<span class="number">1</span>]; - binsum -= sir[<span class="number">2</span>]; - - yi += w; - } - } - - bitmap.setPixels(pix, <span class="number"></span>, w, <span class="number"></span>, <span class="number"></span>, w, h); - - <span class="keyword">return</span> (bitmap); - } 这里的方法也可以实现高斯模糊的效果,但使用了特殊的算法,比第一种可以快很多,但比起RenderScript还是慢一些 (示例来源 [Android高级模糊技术](http://blog.jobbole.com/63894/)) 实现YAHOO天气的动态模糊效果 YAHOO天气中的背景会随着手指上滑模糊程度加深,实际使用中发现怎么都达不到那样流畅的效果,因为手势刷新的速度很快,每一帧都去重新模糊计算一遍,还是会有延迟,造成页面卡顿。后来在一次偶然的开发中发现其实不需要每一帧都重新去模糊一遍,而是将图片最大程度模糊一次,之后和原图叠加,通过改变叠加的模糊图片的alpha值来达到不同程度的模糊效果。下面是一个例子,可以看到随着模糊图片alpha值的变化,叠加后产生不同程度的模糊效果。 ...

2015年10月9日 · 18 分钟 · 天边的星星

基于移动平台的多媒体框架——移植Live555到Android上

live555是一个处理流媒体传输对c++库,再Mplayer与vlc中都有用到。我们计划将其加入到自己编写对Android上的播放器中作为流媒体模块,首先就需要将这个库移植到Android上。 1. 首先在官网下载live555对源码并解压。 2. 新建一个Android工程,将源码文件放到一个该工程的jni目录下,如:jni/live。 3. 新建jni/Android.mk文件作为Makefile。将需要编译对源文件加入到LOCAL_SRC_FILES变量,将需要引用对头文件加入到LOCAL_C_INCLUDES,编译过程中会提示需要参数:-fexceptions,于是加入参数LOCAL_CPPFLAGS += -fexceptions。 内容如下: 4. 新建jni/Application.mk文件。由于live555需要引用stl,所以加入: APP_STL := gnustl_shared 5. 运行ndk-build就可以得到live555.so文件啦。

2015年9月18日 · 1 分钟 · 天边的星星