Android实现局部模糊效果

yizhihongxing

下面是Android实现局部模糊效果的完整攻略:

1. 前置条件

  • Android Studio开发环境
  • 模糊效果库:rendererscriptGlide
  • 图片资源

2. 实现流程

2.1 定义模糊效果

使用rendererscript定义模糊效果,可通过以下步骤实现:

  1. 在项目中app/src/main目录下新建RenderScript文件夹,并在其中创建rs文件
  2. 在rs文件中定义模糊效果,具体代码如下:
#pragma version(1)
#pragma rs java_package_name(com.example.myapplication.renderscript)
#pragma rs_fp_relaxed

rs_allocation gInput;
uchar4 __attribute__((kernel)) root(uchar4 in, uint32_t x, uint32_t y) {
    float4 f4 = rsUnpackColor8888(in);
    const float3 weights = {0.299f, 0.587f, 0.114f};
    const float _VignetteOuterRadius = 0.8f;
    const float _VignetteInnerRadius = 0.5f;
    const int _BlurRadius = 25;

    float3 grayscale = dot(weights, f4.rgb);
    float abs = sqrt((x - rsAllocationGetDimX(gInput)/2.0)*(x - rsAllocationGetDimX(gInput)/2.0)
            + (y - rsAllocationGetDimY(gInput)/2.0)*(y - rsAllocationGetDimY(gInput)/2.0))/
                 hypot(rsAllocationGetDimX(gInput), rsAllocationGetDimY(gInput))/sqrt(2);

    float factor = smootherstep(_VignetteOuterRadius, _VignetteInnerRadius, abs);

    float4 sum = 0;
    int kernelSize = 1 + 2 * _BlurRadius;
    float kernel[kernelSize];

    for(int i = 0; i < kernelSize; i++) {
        kernel[i] = 1.0 / (sqrt(2 * 3.1415926) * _BlurRadius) * exp(-0.5 * ((i - _BlurRadius) / _BlurRadius) * ((i - _BlurRadius) / _BlurRadius));
        sum += rsUnpackColor8888(*(const uchar4 *) rsGetElementAt(gInput, x + i - _BlurRadius, y));
    }
    sum /= sum.w;
    return rsPackColorTo8888(mix(grayscale.rgb, sum.rgb, factor), f4.a);
}

其中,代码定义了灰度值、虚化半径、Vignette特效和高斯滤波等参数。

2.2 引入模糊效果库

在app工程的build.gradle中添加模糊库的引用,具体代码如下:

defaultConfig {
    ...
    renderscriptTargetApi 19
    renderscriptSupportModeEnabled true
}
dependencies {
    implementation 'androidx.renderscript:renderscript:1.0.0'
    implementation 'jp.wasabeef:glide-transformations:3.0.1'
}

其中,renderscript第一行指定了renderscript的target版本为19,第二行开启renderscript的support库。

2.3 实现局部模糊效果

通过引用模糊效果库,可以在线程中把图片转化为Drawable类型,并将其转化为模糊效果后的样式。具体代码如下:

Glide.with(this).load(R.drawable.image)
        .apply(RequestOptions.bitmapTransform(new BlurTransformation(getResources().getDimensionPixelSize(R.dimen.radius))))
        .into(mResult);

其中,Radius为模糊半径,可以在DIMEN文件中定义。

至此,Android实现局部模糊效果的流程已经介绍完毕。

2.4 具体实现示例一

通过Glide实现局部模糊效果:

  1. 在app的build.gradle中引入Glide库,具体代码如下:
dependencies {
    ...
    implementation 'com.github.bumptech.glide:glide:4.9.0'
    annotationProcessor 'com.github.bumptech.glide:compiler:4.9.0'
}
  1. 在xml文件中加入ImageView组件,并将其引用:
<androidx.appcompat.widget.AppCompatImageView
    android:id="@+id/result"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:scaleType="fitXY" />
  1. 加载图片并转化为Drawable类型:
Glide.with(this).load(R.drawable.image)
        .apply(RequestOptions.bitmapTransform(new BlurTransformation(getResources().getDimensionPixelSize(R.dimen.radius))))
        .into(mResult);
  1. 代码具体实现完整示例:
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import android.widget.ImageView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import jp.wasabeef.glide.transformations.BlurTransformation;

public class MainActivity extends AppCompatActivity {
    private ImageView mResult;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mResult = findViewById(R.id.result);
        Glide.with(this).load(R.drawable.owl)
                .apply(RequestOptions.bitmapTransform(new BlurTransformation(getResources().getDimensionPixelSize(R.dimen.radius))))
                .into(mResult);
    }
}

2.5 具体实现示例二

通过RenderScript实现局部模糊效果:

  1. 在app/src/main中新建文件夹RenderScript,并在其中新建文件BlurEffect.rs
#pragma version(1)
#pragma rs java_package_name(com.example.myapplication)

rs_allocation gIn;
rs_allocation gOut;

float  gRadius;

void root(const uchar4* pIn, uchar4* pOut, uint32_t x, uint32_t y) {
    float4 sum = {0.0f, 0.0f, 0.0f, 0.0f};
    float4 temp;
    float   factor;
    uint32_t i, j;
    uint32_t index;
    const int radius = (int)gRadius;
    const int width = rsAllocationGetDimX(gIn);
    const int height = rsAllocationGetDimY(gIn);
    for (j=-radius; j<=radius; j++) {
        for (i=-radius; i<=radius; i++) {
            temp = rsUnpackColor8888(*(pIn + (min(max(x+i, 0), width-1) + min(max(y+j, 0), height-1)*width)));
            factor = exp(-(float)(i*i + j*j) / (gRadius*gRadius));
            sum += temp * factor;
        }
    }
    *pOut = rsPackColorTo8888(sum);
}
  1. 在xml文件中加入ImageView组件,并将其引用:
<androidx.appcompat.widget.AppCompatImageView
    android:id="@+id/result"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:scaleType="fitXY" />
  1. 绘制显示局部模糊效果的图片:
RenderScript rsScript = RenderScript.create(this);
final Allocation input = Allocation.createFromBitmap(rsScript, originalBitmap, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
final Allocation output = Allocation.createTyped(rsScript, input.getType());
final ScriptC_BlurEffect blurEffect = new ScriptC_BlurEffect(rsScript);
blurEffect.set_gIn(input);
blurEffect.set_gOut(output);
blurEffect.set_gRadius(radius);
blurEffect.forEach_root(input, output);
output.copyTo(destBitmap);

ImageView imageview = findViewById(R.id.result);
imageview.setImageBitmap(destBitmap);
  1. 完整示例代码:
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import android.util.Log;
import android.widget.ImageView;
import androidx.renderscript.Allocation;
import androidx.renderscript.Element;
import androidx.renderscript.RenderScript;
import jp.wasabeef.blurry.Blurry;

public class MainActivity extends AppCompatActivity {
    private final int radius = 30;
    private ImageView imageView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        imageView = findViewById(R.id.result);
        Bitmap originalBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.owl);
        Bitmap destBitmap = Bitmap.createBitmap(originalBitmap.getWidth(), originalBitmap.getHeight(), originalBitmap.getConfig());

        RenderScript rsScript = RenderScript.create(this);
        final Allocation input = Allocation.createFromBitmap(rsScript, originalBitmap, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
        final Allocation output = Allocation.createTyped(rsScript, input.getType());
        final ScriptC_BlurEffect blurEffect = new ScriptC_BlurEffect(rsScript);
        blurEffect.set_gIn(input);
        blurEffect.set_gOut(output);
        blurEffect.set_gRadius(radius);
        blurEffect.forEach_root(input, output);
        output.copyTo(destBitmap);

        ImageView imageview = findViewById(R.id.result);
        imageview.setImageBitmap(destBitmap);
    }
}

这就是实现局部模糊效果的完整流程和示例。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Android实现局部模糊效果 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • 程序员实用工具 推荐一款代码统计神器gitstats

    程序员实用工具推荐一款代码统计神器gitstats 在软件开发过程中,代码统计是一个非常重要的环节。它可以帮助我们了解代码的规模、结构质量,从而好地管理和优化代码。在这里,我向大家推荐一款代码统计神器——gitstats。 基本概念 gitstats一个基于 Git 仓库的代码统计工具,它可以生成各种有用的统计信息,包括代码行数、提交次数、活度、贡献者等等。…

    other 2023年5月7日
    00
  • Android中SparseArray性能优化的使用方法

    Android中SparseArray性能优化的使用方法 在Android应用程序中,大量使用集合类型的数据结构是很常见的。在处理大量数据时,如果使用不合适的数据结构,就容易导致数据的访问和处理速度变慢。在这篇文章中,我们将介绍一种名为SparseArray的数据结构,它可以在处理大量数据时优化访问速度。本文将包含如下内容: 什么是SparseArray S…

    other 2023年6月28日
    00
  • jquery datatable服务端分页

    jQuery Datatable是一个基于jQuery的插件,它是一种表格控件,提供了丰富的功能,例如:分页、排序、搜索、过滤、分组、导出等。jquery datatable服务端分页就是将数据从服务端获取,分页显示在前端,而不是将所有数据一次性显示在前端,以提高数据处理效率。下面是jquery datatable服务端分页的完整攻略: 步骤一:引入jQue…

    other 2023年6月27日
    00
  • 关于自动化测试框架pytest的Fixture固件

    关于自动化测试框架pytest的Fixture固件攻略 什么是Fixture固件? 在pytest中,Fixture固件是一种用于提供测试环境的机制。它可以在测试用例执行之前或之后执行一些预定义的操作,例如创建、初始化或清理测试数据、启动或关闭服务等。Fixture固件可以帮助我们更方便地编写和管理测试用例。 如何使用Fixture固件? 1. 定义Fixt…

    other 2023年8月21日
    00
  • High on life画面模糊怎么办 画面不清晰的解决方法

    High on life画面模糊怎么办 画面不清晰的解决方法 如果您在玩High on life游戏时发现画面模糊或不清晰,不要担心,下面的方法可能可以帮助您解决这个问题。 方法一:调整游戏设置 首先尝试调整游戏设置。在游戏菜单中选择“选项”,然后选择“视频”。尝试调整分辨率、图形质量和视觉效果等选项以获得更清晰的图像。另外,如果您正在使用超过60Hz的屏幕…

    other 2023年6月27日
    00
  • ASP.NET中利用Segments取得URL的文件名的一种方法分享

    ASP.NET中利用Segments取得URL的文件名是指可以通过一系列的代码操作,获取当前URL所指向的页面或文件名,然后进行进一步的处理。下面是一个基于代码操作的攻略: 步骤1:获取URL的所有Segments 首先,我们需要获取当前URL的所有Segments,这可以通过内置对象Request的属性Url属性和Segments属性来获取。例如,以下代码…

    other 2023年6月26日
    00
  • 详解Java继承中属性、方法和对象的关系

    关于“详解Java继承中属性、方法和对象的关系”的攻略,我将从以下几个方面进行讲解: 继承的概念及特点 继承中属性的关系及访问方式 继承中方法的关系及重写方式 继承中对象的关系及实例化方式 示例说明 1. 继承的概念及特点 继承是面向对象编程中的一种重要机制,它允许定义一个类,该类继承自另一个已经存在的类,从而继承其属性和方法。继承的特点主要包括以下几个方面…

    other 2023年6月27日
    00
  • go mode tidy出现报错go: warning: “all“ matched no packages的解决方法

    当在使用Go语言的时候,可能会遇到go mode tidy出现报错go: warning: “all“ matched no packages,这时候需要进行排查解决此问题。以下是解决该问题的详细攻略。 问题产生原因 在执行go mode tidy的时候,可能会碰到go: warning: “all“ matched no packages的提示,这种情况一…

    other 2023年6月26日
    00
合作推广
合作推广
分享本页
返回顶部