Android实现局部模糊效果

下面是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日

相关文章

  • 【abp框架系列学习】模块系统(4)之插件示例开发

    ABP框架系列学习:模块系统(4)之插件示例开发 ABP框架中的插件是一种可拔的模块,可以在应用程序运行时动态加载和卸载。本攻略将介绍如何使用ABP框架开发插件例,包括创建插件项目、实现插件接口、注册插件等。 创建插件项目 使用ABP框架创建插件项目的骤如下: 打开Visual Studio,创建一个新的ABP解决方案。 在解决方案中,右键单击“解方案”节点…

    other 2023年5月7日
    00
  • iOS创建对象的不同姿势详解

    iOS创建对象的不同姿势详解 在iOS开发中,我们可以使用多种方式来创建对象。以下是常见的两种方式: 1. 使用alloc和init方法 这是最常见的创建对象的方式。我们首先使用alloc方法来分配内存空间,然后使用init方法来初始化对象。 示例代码: NSString *name = [[NSString alloc] initWithString:@\…

    other 2023年10月14日
    00
  • 如何使用织梦tag列表调用自定义字段附加字段?

    如何使用织梦tag列表调用自定义字段附加字段? 开启自定义字段附加字段功能在织梦后台的“系统管理”->“系统基本参数设置”->“内容管理参数”中,找到“是否使用自定义字段附加字段”,选择“使用”,并保存更改。 为文章添加自定义字段和附加字段在文章编辑页面找到“自定义字段”部分,填写自定义字段名称和对应的值。例如,可以添加一个名为“banner”值…

    other 2023年6月25日
    00
  • C# TSC打印二维码和条形码的实现方法

    C# TSC打印二维码和条形码的实现方法 在C# TSC打印中,二维码和条形码的打印是非常常见的操作。本文将介绍如何使用C# TSC实现二维码和条形码的打印。 TSC打印机介绍 TSC打印机是一款专业的条码打印机,适用于各种规格的标签纸,支持多种打印技术,能够在各种应用场景中高效稳定地打印标签。 打印二维码 在C# TSC中,打印二维码的方法是使用指令^BQ…

    other 2023年6月26日
    00
  • RSync实现文件同步备份配置详解

    RSync实现文件同步备份配置详解 什么是RSync RSync (remote synchronization) 是一个快速、灵活、可靠的远程文件复制工具。 常用于将数据从一个位置同步到另一个位置(比如从本地服务器同步到远程服务器),也用于备份、镜像、迁移数据。 RSync具有以下特点: 可以在本地或远程之间进行同步,支持使用SSH等网络协议进行安全连接 …

    other 2023年6月25日
    00
  • islider—可能是最流畅的移动端滑动组件

    以下是关于“islider—可能是最流畅的移动端滑动组件”的完整攻略,包括定义、特点、使用方法、示例说明和注意事项。 定义 iSlider是一款基于Webkit CSS3动画和JavaScript的移动端滑动组件,可以实现图片、文字、HTML等内容的滑动切换效果。iSlider支持多种滑动效果,包括淡入淡出、旋转、翻转、翻页等。 特点 iSlider的特点包…

    other 2023年5月8日
    00
  • C++浅析类与对象的基础

    C++浅析类与对象的基础 在C++中,类是一种用户自定义的数据类型,它是一种封装了数据和函数的实体。对象是类的一个实例,它表示一个具体的个体,可以通过对象来调用类中定义的函数或访问类中定义的数据。 类的定义 类的定义以class关键字开头,后面跟类的名称和类的定义体。类的定义体由类的成员变量和成员函数组成。类的访问修饰符public、private和prot…

    other 2023年6月27日
    00
  • 小米AI通话如何自定义内容?小米AI通话自定义内容教程

    小米AI通话自定义内容攻略 小米AI通话是一款基于语音识别、自然语言处理等人工智能技术的智能语音助手。通过自定义小米AI通话内容,可以让小米AI通话更好地适配不同的场景和任务,提高用户的交互体验。下面详细讲解小米AI通话如何自定义内容和对应的教程。 1. 自定义小米AI通话技能 要自定义小米AI通话的内容,需要先了解小米AI通话技能的概念。小米AI通话技能是…

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