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日

相关文章

  • qt创建.csv文件

    qt创建.csv文件 在Qt中,我们可以使用QFile类来创建和操作文件。创建CSV文件的过程与创建任何其他类型的文件非常相似。 CSV(Comma Separated Values)文件是一种常用的文件格式,通常用于存储具有类似表格结构的数据。CSV格式的文件可以使用各种软件轻松处理,包括Microsoft Excel、Google Sheets和Open…

    其他 2023年3月28日
    00
  • r语言sample函数

    当然,我很乐意为您提供有关“R语言sample函数”的完整攻略。以下是详细的步骤和两个示例: 1. 什么是sample函数? sample函数是R语言中的一个随机抽样函数,可以用于从一个向量或数据框中随机抽取指定数量的元素。 2. sample函数的语法 sample函数的语法如下: sample(x, size, replace = FALSE, prob…

    other 2023年5月6日
    00
  • 4g模块是什么?4g模块的工作原理

    什么是4G模块? 4G模块是一种基于4G网络的通信模块,主要用于将设备连接到互联网。它能够提供稳定、高速的网络连接,方便人们在无线网络环境下进行信息交流和数据传输。 4G模块的工作原理 4G模块主要由三个部分组成,即模块芯片、射频前端和天线。 模块芯片负责将数据转换成数字信号,并将其发送到射频前端。射频前端则负责调制数字信号,并将其发送到天线,最终以无线电波…

    其他 2023年4月16日
    00
  • 玩转smartqq之登录

    以下是关于“玩转smartqq之登录”的完整攻略,包括登录过程、示例说明等。 1. 登录过程 smartqq是一款基于WebQQ协议的第三方QQ客户端,可以在Linux、Mac OS X、Windows等多个平台上使用。以下是smartqq登录的完整攻略: 获取二维码:打开smartqq客户端,点击“登录”按钮,获取二维码。 扫描二维码:使用手机QQ或其他支…

    other 2023年5月7日
    00
  • linux怎么查看jar包内容

    当然,我很乐意为您提供有关“Linux如何查看jar包内容”的完整攻略。以下是详细的步骤和两个示例: 1 查看jar包内容 在Linux中,可以使用命令行工具来查看jar包的内容。以下是两种方法: 1.1 使用jar命令 可以使用jar命令来查看jar包的内容。例如: jar tf example.jar 在这个示例中,我们使用jar命令来查看example…

    other 2023年5月6日
    00
  • PyCharm专业最新版2019.1安装步骤(含激活码)

    PyCharm专业最新版2019.1安装步骤(含激活码) PyCharm是一款基于Python开发的集成开发环境,拥有丰富的功能和插件,受到Python开发者的广泛喜爱。本文将介绍如何安装PyCharm专业最新版2019.1,并提供激活码。 步骤一:下载安装包 首先,从JetBrains官网(https://www.jetbrains.com/pycharm…

    other 2023年6月27日
    00
  • PDF提示文件名与真实的文件名怎么办?

    当需要下载PDF文件时,有些网站的文件名可能与实际文件名不符,可能会出现如下问题: 点击下载链接后默认弹出的提示框中显示的文件名与实际文件名不同。 下载文件后保存至本地的文件名与实际文件名不同。 针对这种情况,我们可以通过修改HTTP响应头中的Content-Disposition字段来解决。 Content-Disposition Content-Disp…

    other 2023年6月27日
    00
  • locate命令详解

    当然,我很乐意为您提供有关“locate命令详解”的完整攻略。以下是详细的步骤和两个示例: 1 locate命令详解 locate命令是Linux系统中的一个命令行工具,用于快速查找文件。它可以在系统中搜索文件名或路径,并返回匹配的文件列表。 2 locate命令的使用 以下是使用locate命令的方法: 2.1 安装locate命令 在大多数Linux发行…

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