源作者博客地址: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'
将要处理的图片素材放进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);
}
}
布局文件:
效果:
可以看到,只是将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;
}
}
布局文件:
效果:
分析:我们这里通过一个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,可以进行滤镜切换和饱和度调整,效果如下:
感兴趣的朋友可以下载源码:点此下载
附录
附上部分滤镜类型的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" 【通常用于创建两个图像之间的动画变暗模糊效果】