GPUImage简介

  GPUImage 是iOS下一个开源的基于GPU的图像处理库,提供各种各样的图像处理滤镜,并且支持照相机和摄像机的实时滤镜。GPUImage for Android是它在Android下的实现,同样也是开源的。其中提供了几十多种常见的图片滤镜API,且其机制是基于GPU渲染,处理速度相应也比较快,是一个不错的图片实时处理框架。

GitHub地址:https://github.com/CyberAgent/android-gpuimage

GPUImage使用
环境搭建

首先,要使用这个库自然是要先导入依赖,在app的gradle文件中添加:

compile 'jp.co.cyberagent.android.gpuimage:gpuimage-library:1.4.1'

将要处理的图片素材放进Assets文件夹,如果目录中没有这个文件夹,可以自己新建一个:
 

我这里以名为link.jpg的图片作为素材复制进去:

素材原图link.jpg:


API调用:

GPUImage主要通过一个GPUImageFilter类来提供各种滤镜效果实现类,比如我们来实现一个将图片变成黑白的滤镜:

public class GPUActivity extends Activity{
     
        private GPUImage gpuImage;
        //显示处理结果
        private ImageView resultIv;
     
        protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_gpu);
            resultIv = (ImageView) findViewById(R.id.resultIv);
     
            //获得Assets资源文件
            AssetManager as = getAssets();
            InputStream is = null;
            Bitmap bitmap = null;
            try {
                //注意名字要与图片名字一致
                    is = as.open("link.jpg");
                    bitmap = BitmapFactory.decodeStream(is);
                    is.close();
            } catch (IOException e) {
                    Log.e("GPUImage", "Error");
            }
     
            // 使用GPUImage处理图像
            gpuImage = new GPUImage(this);
            gpuImage.setImage(bitmap);
            gpuImage.setFilter(new GPUImageGrayscaleFilter());
            bitmap = gpuImage.getBitmapWithFilterApplied();
            //显示处理后的图片
            resultIv.setImageBitmap(bitmap);
        }
    }

布局文件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <ImageView
                   android:id="@+id/resultIv"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                />
    </LinearLayout>

效果:

可以看到,只是将Assets中的资源转换为bitmap,再通过GPUImage对象来设置图片(setImage)和过滤(setImage),在setFilter中传进了一个GPUImageGrayscaleFilter实例,表示设置为灰度滤镜,最终再通过调用getBitmapWithFilterApplied()来应用以上设置,并返回一个处理后的bitmap对象,再将其显示出来。

因此,如果你要使用其他滤镜,只需替换setFilter的参数便可以,GPUImage提供了50多种滤镜类。
 
调整饱和度|亮度

在GPUImage的一些滤镜类中,有一些是带有数值参数的构造方法,传进不同的值会有不同程度的效果。

调整饱和度主要通过这个方法:GPUImageSaturationFilter(float saturation)

代码:
    public class GPUActivity extends Activity{
     
        private GPUImage gpuImage;
        //显示处理结果
        private ImageView resultIv;
        //进度条
        private SeekBar seekbar;
     
        protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_gpu);
            resultIv = (ImageView) findViewById(R.id.resultIv);
     
            seekbar = (SeekBar)this.findViewById(R.id.seekbar);
                seekbar.setMax(10);
                seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
                        @Override
                        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                    //通过进度条的值更改饱和度
                            resultIv.setImageBitmap(getGPUImageFromAssets(progress));
                        }
     
                        @Override
                        public void onStartTrackingTouch(SeekBar seekBar) {
     
                        }
     
                        @Override
                        public void onStopTrackingTouch(SeekBar seekBar) {
     
                        }
                });
     
            
            
            //初始化图片
            resultIv.setImageBitmap(getGPUImageFromAssets(0));
        }
     
        //根据传进来的数值设置素材饱和度
        public Bitmap getGPUImageFromAssets(int progress){
            
            //获得Assets资源文件
            AssetManager as = getAssets();
            InputStream is = null;
            Bitmap bitmap = null;
            try {
                //注意名字要与图片名字一致
                    is = as.open("link.jpg");
                    bitmap = BitmapFactory.decodeStream(is);
                    is.close();
            } catch (IOException e) {
                    Log.e("GPUImage", "Error");
            }
     
            // 使用GPUImage处理图像
            gpuImage = new GPUImage(this);
            gpuImage.setImage(bitmap);
            gpuImage.setFilter(new GPUImageSaturationFilter(progress));
            bitmap = gpuImage.getBitmapWithFilterApplied();
            return bitmap;
        }
    }

布局文件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center_vertical">
        <ImageView
                   android:id="@+id/resultIv"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                />
        <SeekBar
                android:id="@+id/seekbar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:visibility="visible"/>
    </LinearLayout>

效果:

分析:我们这里通过一个seekbar进度条来调整其饱和度大小,一拖动进度条,便调用seekBar的onProgressChanged()方法,并将progress传递给getGPUImageFromAssets()方法,注意到在getGPUImageFromAssets()方法中gpuImage.setFilter(new GPUImageSaturationFilter(progress));将progress设置给了饱和度滤镜,从而调整图片的饱和度。

上面演示了如何通过GPUImage调整饱和度,要实现亮度的调整仅需将Filter改为GPUImageBrightnessFilter,并且在设置progress的时候在区间0-1之间设置便可,如下:

gpuImage.setFilter(new GPUImageBrightnessFilter(progress*0.1f));

网络图片滤镜处理

上面的demo中的Bitmap都是从Assets文件夹中获取而来,但实际开发中可能还有很多情况是通过URL获取网络资源图片,可以通过如下方式:

public class GPUActivity extends Activity{
     
        private GPUImage gpuImage;
        //显示处理结果
        private ImageView resultIv;
     
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_gpu);
            resultIv = (ImageView) findViewById(R.id.resultIv);
     
        //开启异步线程加载图片并处理
            MyAsynTask asynTask = new MyAsynTask();
            asynTask.execute();
     
        }
     
        class MyAsynTask extends AsyncTask<Integer,Integer,Bitmap>{
     
            @Override
            protected Bitmap doInBackground(Integer... params) {
                Bitmap bitmap = getGPUImageFromURL("http://pic36.nipic.com/20131225/15361977_174053547194_2.jpg");
                return bitmap;
            }
     
            @Override
            protected void onPostExecute(Bitmap bitmap) {
                // 使用GPUImage处理图像
                gpuImage = new GPUImage(getApplicationContext());
                gpuImage.setImage(bitmap);
                gpuImage.setFilter(new GPUImageGrayscaleFilter());
                bitmap = gpuImage.getBitmapWithFilterApplied();
                //显示处理后的图片
                resultIv.setImageBitmap(bitmap);
            }
        }
     
        public static Bitmap getGPUImageFromURL(String url) {
            Bitmap bitmap = null;
            try {
                URL iconUrl = new URL(url);
                URLConnection conn = iconUrl.openConnection();
                HttpURLConnection http = (HttpURLConnection) conn;
                int length = http.getContentLength();
                conn.connect();
                // 获得图像的字符流
                InputStream is = conn.getInputStream();
                BufferedInputStream bis = new BufferedInputStream(is, length);
                bitmap = BitmapFactory.decodeStream(bis);
                bis.close();
                is.close();// 关闭流
            } catch (Exception e) {
                e.printStackTrace();
            }
            return bitmap;
        }
    }

当然,还要记得在Application.xml中添加网络访问权限:

<uses-permission android:name="android.permission.INTERNET"></uses-permission>

代码分析:由于访问网络图片,所以需要放在子线程中进行,所以这里通过AsynTask(Android异步线程,不清楚的可以度娘),现在子线程请求完网络图片并转换为Bitmap传递给主线程中对图片进行滤镜处理并显示出来。

最佳实践

在实际开发中可以将这些API封装成一个工具类,只需传入我们的图片资源以及滤镜类型,便可以对图片做出处理:

public class GPUImageUtil {
     
        private static GPUImageFilter filter;
        
        //饱和度、亮度等参数指数
        private static int count;
     
        /**
         * 获取过滤器
         * @param GPUFlag
         * @return 滤镜类型
         */
        public static GPUImageFilter getFilter(int GPUFlag){
            switch (GPUFlag){
                case 1:
                    filter = new GPUImageGrayscaleFilter();
                    break;
                case 2:
                    filter = new GPUImageAddBlendFilter();
                    break;
                case 3:
                    filter = new GPUImageAlphaBlendFilter();
                    break;
                case 4:
                    filter = new GPUImageBilateralFilter();
                    break;
                case 5:
                    filter = new GPUImageBoxBlurFilter();
                    break;
                case 6:
                    filter = new GPUImageBrightnessFilter();
                    break;
                case 7:
                    filter = new GPUImageBulgeDistortionFilter();
                    break;
                case 8:
                    filter = new GPUImageCGAColorspaceFilter();
                    break;
                case 9:
                    filter = new GPUImageChromaKeyBlendFilter();
                    break;
                case 10:
                    filter = new GPUImageColorBalanceFilter();
                    break;
            case 11:
                    filter = new GPUImageSaturationFilter(count);
                    break;                
            }
            return filter;
        }
     
        public static Bitmap getGPUImageFromAssets(Context context,GPUImage gpuImage,int FilterFlag){
            AssetManager as = context.getAssets();
            InputStream is = null;
            Bitmap bitmap = null;
            try {
                is = as.open("link.jpg");
                bitmap = BitmapFactory.decodeStream(is);
                is.close();
            } catch (IOException e) {
                Log.e("GPUImage", "Error");
            }
     
            // 使用GPUImage处理图像
            gpuImage = new GPUImage(context);
            gpuImage.setImage(bitmap);
            gpuImage.setFilter(getFilter(FilterFlag));
            bitmap = gpuImage.getBitmapWithFilterApplied();
            return bitmap;
        }
     
        public static Bitmap getGPUImageFromURL(String url) {
            Bitmap bitmap = null;
            try {
                URL iconUrl = new URL(url);
                URLConnection conn = iconUrl.openConnection();
                HttpURLConnection http = (HttpURLConnection) conn;
                int length = http.getContentLength();
                conn.connect();
                // 获得图像的字符流
                InputStream is = conn.getInputStream();
                BufferedInputStream bis = new BufferedInputStream(is, length);
                bitmap = BitmapFactory.decodeStream(bis);
                bis.close();
                is.close();// 关闭流
                } catch (Exception e) {
                    e.printStackTrace();
                }
            return bitmap;
        }
     
        //调整饱和度、亮度等
        public static void changeSaturation(int curCount){
            GPUImageUtil.count = curCount;
        }
    }

这里只列举了部分作为举例,可以根据自己实际开发想要的滤镜进行添加。

作了一个小Demo,可以进行滤镜切换和饱和度调整,效果如下:

 
感兴趣的朋友可以下载源码:点此下载

附录

附上部分滤镜类型的API中文参照,便于查阅:

"GPUImageFastBlurFilter"                               【模糊】
"GPUImageGaussianBlurFilter"                       【高斯模糊】
"GPUImageGaussianSelectiveBlurFilter"        【高斯模糊,选择部分清晰】
"GPUImageBoxBlurFilter"                                【盒状模糊】
"GPUImageTiltShiftFilter"                                【条纹模糊,中间清晰,上下两端模糊】
"GPUImageMedianFilter.h"                             【中间值,有种稍微模糊边缘的效果】
"GPUImageBilateralFilter"                               【双边模糊】
"GPUImageErosionFilter"                                【侵蚀边缘模糊,变黑白】
"GPUImageRGBErosionFilter"                         【RGB侵蚀边缘模糊,有色彩】
"GPUImageDilationFilter"                               【扩展边缘模糊,变黑白】
"GPUImageRGBDilationFilter"                        【RGB扩展边缘模糊,有色彩】
"GPUImageOpeningFilter"                             【黑白色调模糊】
"GPUImageRGBOpeningFilter"                      【彩色模糊】
"GPUImageClosingFilter"                               【黑白色调模糊,暗色会被提亮】
"GPUImageRGBClosingFilter"                        【彩色模糊,暗色会被提亮】
"GPUImageLanczosResamplingFilter"          【Lanczos重取样,模糊效果】
"GPUImageNonMaximumSuppressionFilter"     【非最大抑制,只显示亮度最高的像素,其他为黑】
"GPUImageThresholdedNonMaximumSuppressionFilter" 【与上相比,像素丢失更多】

"GPUImageCrosshairGenerator"              【十字】
"GPUImageLineGenerator"                       【线条】
"GPUImageTransformFilter"                     【形状变化】
"GPUImageCropFilter"                              【剪裁】
"GPUImageSharpenFilter"                        【锐化】
"GPUImageUnsharpMaskFilter"               【反遮罩锐化】

"GPUImageSobelEdgeDetectionFilter"           【Sobel边缘检测算法(白边,黑内容,有点漫画的反色效果)】
"GPUImageCannyEdgeDetectionFilter"          【Canny边缘检测算法(比上更强烈的黑白对比度)】
"GPUImageThresholdEdgeDetectionFilter"    【阈值边缘检测(效果与上差别不大)】
"GPUImagePrewittEdgeDetectionFilter"         【普瑞维特(Prewitt)边缘检测(效果与Sobel差不多,貌似更平滑)】
"GPUImageXYDerivativeFilter"                        【XYDerivative边缘检测,画面以蓝色为主,绿色为边缘,带彩色】
"GPUImageHarrisCornerDetectionFilter"       【Harris角点检测,会有绿色小十字显示在图片角点处】
"GPUImageNobleCornerDetectionFilter"      【Noble角点检测,检测点更多】
"GPUImageShiTomasiFeatureDetectionFilter" 【ShiTomasi角点检测,与上差别不大】
"GPUImageMotionDetector"                             【动作检测】
"GPUImageHoughTransformLineDetector"      【线条检测】
"GPUImageParallelCoordinateLineTransformFilter" 【平行线检测】

"GPUImageLocalBinaryPatternFilter"        【图像黑白化,并有大量噪点】
"GPUImageLowPassFilter"                          【用于图像加亮】
"GPUImageHighPassFilter"                        【图像低于某值时显示为黑】

"GPUImageSketchFilter"                          【素描】
"GPUImageThresholdSketchFilter"         【阀值素描,形成有噪点的素描】
"GPUImageToonFilter"                             【卡通效果(黑色粗线描边)】
"GPUImageSmoothToonFilter"                【相比上面的效果更细腻,上面是粗旷的画风】
"GPUImageKuwaharaFilter"                     【桑原(Kuwahara)滤波,水粉画的模糊效果;处理时间比较长,慎用】

"GPUImageMosaicFilter"                         【黑白马赛克】
"GPUImagePixellateFilter"                       【像素化】
"GPUImagePolarPixellateFilter"              【同心圆像素化】
"GPUImageCrosshatchFilter"                  【交叉线阴影,形成黑白网状画面】
"GPUImageColorPackingFilter"              【色彩丢失,模糊(类似监控摄像效果)】

"GPUImageVignetteFilter"                        【晕影,形成黑色圆形边缘,突出中间图像的效果】
"GPUImageSwirlFilter"                               【漩涡,中间形成卷曲的画面】
"GPUImageBulgeDistortionFilter"            【凸起失真,鱼眼效果】
"GPUImagePinchDistortionFilter"            【收缩失真,凹面镜】
"GPUImageStretchDistortionFilter"         【伸展失真,哈哈镜】
"GPUImageGlassSphereFilter"                  【水晶球效果】
"GPUImageSphereRefractionFilter"         【球形折射,图形倒立】
    
"GPUImagePosterizeFilter"                 【色调分离,形成噪点效果】
"GPUImageCGAColorspaceFilter"      【CGA色彩滤镜,形成黑、浅蓝、紫色块的画面】
"GPUImagePerlinNoiseFilter"              【柏林噪点,花边噪点】
"GPUImage3x3ConvolutionFilter"      【3x3卷积,高亮大色块变黑,加亮边缘、线条等】
"GPUImageEmbossFilter"                   【浮雕效果,带有点3d的感觉】
"GPUImagePolkaDotFilter"                 【像素圆点花样】
"GPUImageHalftoneFilter"                  【点染,图像黑白化,由黑点构成原图的大致图形】

混合模式 Blend

"GPUImageMultiplyBlendFilter"            【通常用于创建阴影和深度效果】
"GPUImageNormalBlendFilter"               【正常】
"GPUImageAlphaBlendFilter"                 【透明混合,通常用于在背景上应用前景的透明度】
"GPUImageDissolveBlendFilter"             【溶解】
"GPUImageOverlayBlendFilter"              【叠加,通常用于创建阴影效果】
"GPUImageDarkenBlendFilter"               【加深混合,通常用于重叠类型】
"GPUImageLightenBlendFilter"              【减淡混合,通常用于重叠类型】
"GPUImageSourceOverBlendFilter"       【源混合】
"GPUImageColorBurnBlendFilter"          【色彩加深混合】
"GPUImageColorDodgeBlendFilter"      【色彩减淡混合】
"GPUImageScreenBlendFilter"                【屏幕包裹,通常用于创建亮点和镜头眩光】
"GPUImageExclusionBlendFilter"            【排除混合】
"GPUImageDifferenceBlendFilter"          【差异混合,通常用于创建更多变动的颜色】
"GPUImageSubtractBlendFilter"            【差值混合,通常用于创建两个图像之间的动画变暗模糊效果】
"GPUImageHardLightBlendFilter"         【强光混合,通常用于创建阴影效果】
"GPUImageSoftLightBlendFilter"           【柔光混合】
"GPUImageChromaKeyBlendFilter"       【色度键混合】
"GPUImageMaskFilter"                           【遮罩混合】
"GPUImageHazeFilter"                            【朦胧加暗】
"GPUImageLuminanceThresholdFilter" 【亮度阈】
"GPUImageAdaptiveThresholdFilter"     【自适应阈值】
"GPUImageAddBlendFilter"                    【通常用于创建两个图像之间的动画变亮模糊效果】
"GPUImageDivideBlendFilter"                 【通常用于创建两个图像之间的动画变暗模糊效果】

Android图像滤镜框架GPUImage从配置到应用的更多相关文章

  1. 【转载】从零实现3D图像引擎:(1)环境配置与项目框架

    原文:从零实现3D图像引擎:(1)环境配置与项目框架 0. 要学懂3D程序设计,必然要精通3D相关的线性代数.3D几何.复分析等相关知识,我也因为如此才开始这个博客系列的写作,不自己实现,就不是自己的 ...

  2. 各种Android UI开源框架 开源库

    各种Android UI开源框架 开源库 转 https://blog.csdn.net/zhangdi_gdk2016/article/details/84643668 自己总结的Android开源 ...

  3. Android的多媒体框架OpenCore介绍

    网上资料很少, 不过还是找到一个比较详细的说明: 特地在此整理了下: 地址:http://blog.csdn.net/djy1992/article/details/9339787 分为几个阶段: 1 ...

  4. android开源项目框架大全:

    android开源项目框架大全: 1.多页切换TabHost9 高仿网易云音乐客户端的Home页面切换Tabhost 高仿网易云音乐客户端的Home页面切换Tabhost,并且三角形是透明的,实现方式 ...

  5. 25类Android常用开源框架

    1.图片加载,缓存,处理 框架名称 功能描述 Android Universal Image Loader 一个强大的加载,缓存,展示图片的库,已过时 Picasso 一个强大的图片下载与缓存的库 F ...

  6. Android开源测试框架学习

    近期因工作需要,分析了一些Android的测试框架,在这也分享下整理完的资料. Android测试大致分三大块: 代码层测试 用户操作模拟,功能测试 安装部署及稳定性测试 代码层测试 对于一般java ...

  7. Android studio下gradle Robolectric单元测试配置

    android studio下gradle Robolectric单元测试配置 1.Robolectric Robolectric是一个基于junit之上的单元测试框架.它并不依赖于Android提供 ...

  8. 60.Android通用流行框架大全

    转载:https://segmentfault.com/a/1190000005073746 Android通用流行框架大全 1. 缓存 名称 描述 DiskLruCache Java实现基于LRU的 ...

  9. 简析Android 兼容性测试框架CTS使用

    一.什么是兼容性测试? 1)为用户提供最好的用户体验,让更多高质量的APP可以顺利的运行在此平台上 2)让程序员能为此平台写更多的高质量的应用程序 3)可以更好的利用Android应用市场 二.CTS ...

随机推荐

  1. 【java异常】expected at least 1 bean which qualifies as autowire candidate for this depende

    1.查看接口实现类是否加入注解,如service.repository等 2.查看spring配置文件是否自动扫描包    <context:component-scan base-packag ...

  2. three.js 设置透明度

    原文:https://www.cnblogs.com/amy2011/p/6148736.html 材质: 材质就像物体的皮肤,决定了几何体的外表,例如是否像草地/金属,是否透明,是否显示线框等 Th ...

  3. ESA2GJK1DH1K基础篇: STM32+Wi-Fi(AT指令版)实现MQTT源码讲解

    前言 注: 本程序发送心跳包,发送温湿度,返回控制数据这三个发送是单独的,有可能凑到一起发. 由于本身程序就是复杂性的程序,所以这节程序没有使用中断发送,没有使用环形队列发送,为了避免多条消息可能凑到 ...

  4. 洛谷p2827蚯蚓题解

    题目 算法标签里的算法什么的都不会啊 什么二叉堆?? qbxt出去学习的时候讲的,一段时间之前做的,现在才写到博客上的 维护3个队列,队列1表示最开始的蚯蚓,队列2表示每一次被切的蚯蚓被分开的较长的那 ...

  5. 【JZOJ5739】【20190706】毒奶

    题目 有\(n\)个现实城市,另有\(n\)个幻想城市 原图中在现实城市存在\(m\)条边,在幻想城市存在\(m-1-n\)条边 一个排列是合法的当且进当显示城市 \(i\) 向幻想城市 \(p_i\ ...

  6. px转rem vue vscode

    1.vscode中安装px2rem 2.打开settings.json ,新增  "px2rem.rootFontSize": 75, 3.重启vscode 4.可以转换了

  7. MySQL重要知识点

    可能是全网最好的MySQL重要知识点 |  mp.weixin.qq.com 点击蓝色“程序猿DD”关注我 回复“资源”获取独家整理的学习资料! 标题有点标题党的意思,但希望你在看了文章之后不会有这个 ...

  8. 深入解密来自未来的缓存-Caffeine

    1.前言 读这篇文章之前希望你能好好的阅读: 你应该知道的缓存进化史 和 如何优雅的设计和使用缓存? .这两篇文章主要从一些实战上面去介绍如何去使用缓存.在这两篇文章中我都比较推荐Caffeine这款 ...

  9. kali 触摸板手势之fusuma

    1.执行如下命令进行安装 *fusuma 需要在ruby环境下运行,若计算机不支持ruby,则先执行:apt-get install ruby apt-get update apt-get insta ...

  10. Maven 教程(7)— Maven使用的最佳实践

    原文地址:https://blog.csdn.net/liupeifeng3514/article/details/79544201 1.设置MAVEN_OPTS环境变量 通常需要设置MAVEN_OP ...