Android图像滤镜框架GPUImage从配置到应用

源作者博客地址:http://blog.csdn.net/it_zjyang/article/details/52268918

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

GitHub地址:https://github.com/CyberAgent/android-gpuimageGPUImage使用
环境搭建
首先,要使用这个库自然是要先导入依赖,在app的gradle文件中添加:

    compile 'jp.co.cyberagent.android.gpuimage:gpuimage-library:1.4.1'
Android图像滤镜框架GPUImage从配置到应用_第1张图片

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


Android图像滤镜框架GPUImage从配置到应用_第2张图片

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


素材原图link.jpg:


Android图像滤镜框架GPUImage从配置到应用_第3张图片

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);  
    }  
}  

布局文件:

  
      
  

效果:


Android图像滤镜框架GPUImage从配置到应用_第4张图片

可以看到,只是将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;  
    }  
}  

布局文件:

  
  
  
  

效果:


Android图像滤镜框架GPUImage从配置到应用_第5张图片

分析:我们这里通过一个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{  

    @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中添加网络访问权限:

  

代码分析:由于访问网络图片,所以需要放在子线程中进行,所以这里通过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,可以进行滤镜切换和饱和度调整,效果如下:


Android图像滤镜框架GPUImage从配置到应用_第6张图片

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

附录
附上部分滤镜类型的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从配置到应用)