Android中如何对ImageView进行模糊处理

20

我有一个ImageView,并且我通过编程的方式设置图像资源,就像这样:

int resourceId = getResources().getIdentifier("imagename", "drawable", "mypackage");
imgLock.setImageResource(resourceId);

有没有一种简单的方法可以显示我的ImageView并加上模糊效果?


https://dev59.com/5nI95IYBdhLWcg3w-DH0#10028267 - Shivam Verma
在“Bitmap bitmap = sentBitmap.copy(sentBitmap.getConfig(), true);”这一行代码上,它给了我一个“NullPointerException”。 - aletede91
请查看我的答案,这肯定能解决你的问题。 - sujith s
13个回答

17

您可以使用Glide转换https://github.com/wasabeef/glide-transformations,只需一行代码即可模糊图像。

Glide.with(this).load(R.drawable.demo)
    .bitmapTransform(new BlurTransformation(context))
    .into((ImageView) findViewById(R.id.image));

7
import android.renderscript.Allocation;
import android.renderscript.Element;
import android.renderscript.RenderScript;
import android.renderscript.ScriptIntrinsicBlur;

Bitmap blurred = blurRenderScript(this,yourBitmap, 25);
//second parametre is radius
yourImageView.setImageBitmap(blurred); 

@SuppressLint("NewApi")
public static Bitmap blurRenderScript(Context context,Bitmap smallBitmap, int radius) {
try {
        smallBitmap = RGB565toARGB888(smallBitmap);
    } catch (Exception e) {
        e.printStackTrace();
    }

    Bitmap bitmap = Bitmap.createBitmap(
            smallBitmap.getWidth(), smallBitmap.getHeight(),
            Bitmap.Config.ARGB_8888);

    RenderScript renderScript = RenderScript.create(context);

    Allocation blurInput = Allocation.createFromBitmap(renderScript, smallBitmap);
    Allocation blurOutput = Allocation.createFromBitmap(renderScript, bitmap);

    ScriptIntrinsicBlur blur = ScriptIntrinsicBlur.create(renderScript,
            Element.U8_4(renderScript));
    blur.setInput(blurInput);
    blur.setRadius(radius); // radius must be 0 < r <= 25
    blur.forEach(blurOutput);

    blurOutput.copyTo(bitmap);
    renderScript.destroy();

    return bitmap;
}

private static Bitmap RGB565toARGB888(Bitmap img) throws Exception {
    int numPixels = img.getWidth() * img.getHeight();
    int[] pixels = new int[numPixels];

    //Get JPEG pixels.  Each int is the color values for one pixel.
    img.getPixels(pixels, 0, img.getWidth(), 0, 0, img.getWidth(), img.getHeight());

    //Create a Bitmap of the appropriate format.
    Bitmap result = Bitmap.createBitmap(img.getWidth(), img.getHeight(), Bitmap.Config.ARGB_8888);

    //Set RGB pixels.
    result.setPixels(pixels, 0, result.getWidth(), 0, 0, result.getWidth(), result.getHeight());
    return result;
}

1
这个适用于API级别17及以上,对于较低的API级别,有一个支持库android.support.v8.renderscript.ScriptIntrinsicBlur - gregn3
1
不错。没有外部库。简单而短小的解决方案。谢谢。 - Sermilion
1
阅读了这些说明(https://github.com/xamarin/docs-archive/tree/master/Recipes/android/other_ux/drawing/blur_an_image_with_renderscript)后,似乎将blurRenderScript()和RGB565toARGB888()方法都放在一个`AsyncTask`中是一个很好的实践。 - Aliton Oliveira
RenderScript已被弃用... - Crisic

3

有许多可用的库,您可以使用其中任何一个。我更喜欢使用模糊库。它非常简单和优化。

依赖项:

 dependencies {
    compile 'jp.wasabeef:blurry:4.x.x'
}

函数

  • Blurry.with(context).radius(25).sampling(2).onto(rootView) // 对整个界面进行模糊处理
  • // 从 View Blurry.with(context).capture(view).into(imageView) // 对指定的视图进行模糊处理,并将结果显示在另一个 ImageView 中
  • // 从 Bitmap Blurry.with(context).from(bitmap).into(imageView) // 对指定的 Bitmap 进行模糊处理,并将结果显示在 ImageView 中

模糊选项

  • 半径
  • 降采样
  • 颜色过滤器
  • 异步支持
  • 动画(仅叠加层)
Blurry.with(context)
  .radius(10)
  .sampling(8)
  .color(Color.argb(66, 255, 255, 0))
  .async()
  .animate(500)
  .onto(rootView);

直接获取位图

// Sync
val bitmap = Blurry.with(this)
  .radius(10)
  .sampling(8)
  .capture(findViewById(R.id.right_bottom)).get()
imageView.setImageDrawable(BitmapDrawable(resources, bitmap))

// Async
Blurry.with(this)
  .radius(25)
  .sampling(4)
  .color(Color.argb(66, 255, 255, 0))
  .capture(findViewById(R.id.left_bottom))
  .getAsync {
    imageView.setImageDrawable(BitmapDrawable(resources, it))
  }

2

这里是原始回答链接

Android 12预览版1带有内置的模糊功能,现在我们不需要依赖外部库了。以下是代码:

imageView.setRenderEffect(
        RenderEffect.createBlurEffect(
            20.0f, 20.0f, SHADER_TITLE_MODE
        )
)

1
private Bitmap CreateBlurredImage (int radius)
{
   // Load a clean bitmap and work from that
    Bitmap originalBitmap=
    BitmapFactory.DecodeResource(Resources,Resource.Drawable.dog_and_monkeys);

// Create another bitmap that will hold the results of the filter.
Bitmap blurredBitmap;
blurredBitmap = Bitmap.CreateBitmap (originalBitmap);

// Create the Renderscript instance that will do the work.
RenderScript rs = RenderScript.Create (this);

// Allocate memory for Renderscript to work with
Allocation input = Allocation.CreateFromBitmap (rs, originalBitmap, Allocation.MipmapControl.MipmapFull, AllocationUsage.Script);
Allocation output = Allocation.CreateTyped (rs, input.Type);

// Load up an instance of the specific script that we want to use.
ScriptIntrinsicBlur script = ScriptIntrinsicBlur.Create (rs, Element.U8_4 (rs));
script.SetInput (input);

// Set the blur radius
script.SetRadius (radius);

// Start the ScriptIntrinisicBlur
script.ForEach (output);

// Copy the output to the blurred bitmap
output.CopyTo (blurredBitmap);

return blurredBitmap;

}

protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);

SetContentView (Resource.Layout.Main);
_imageView = FindViewById<ImageView> (Resource.Id.originalImageView);

_seekbar = FindViewById<SeekBar> (Resource.Id.seekBar1);
_seekbar.StopTrackingTouch += BlurImageHandler;

}

private void BlurImageHandler (object sender, SeekBar.StopTrackingTouchEventArgs e)
{
int radius = e.SeekBar.Progress;
if (radius == 0) {
    // We don't want to blur, so just load the un-altered image.
    _imageView.SetImageResource (Resource.Drawable.dog_and_monkeys);
} else {
    DisplayBlurredImage (radius);
}

}

private void DisplayBlurredImage (int radius)
{
_seekbar.StopTrackingTouch -= BlurImageHandler;
_seekbar.Enabled = false;

ShowIndeterminateProgressDialog ();

Task.Factory.StartNew (() => {
    Bitmap bmp = CreateBlurredImage (radius);
    return bmp;
})
.ContinueWith (task => {
    Bitmap bmp = task.Result;
    _imageView.SetImageBitmap (bmp);
    _seekbar.StopTrackingTouch += BlurImageHandler;
    _seekbar.Enabled = true;
    DismissIndeterminateProgressDialog ();
}, TaskScheduler.FromCurrentSynchronizationContext ());

}

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent">
    <SeekBar
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:id="@+id/seekBar1"
            android:max="25" />
    <ImageView
            android:src="@drawable/dog_and_monkeys"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:id="@+id/originalImageView" />
</LinearLayout>

点击此处查看详细的代码示例


1

只需简单地使用这个库 https://github.com/ChathuraHettiarachchi/BlurIM,我遇到了模糊转换类错误的问题,所以不能使用Glide转换,但这个库很好用。

BlurImage.withContext(this)
     .blurFromResource(R.drawable.YOUR_RESOURCE)
     .into(imageView);

0

您可以使用RenderScript来实现,如此处所述,或者您可以使用stackblur库在图像中创建模糊效果。

使用stackblur库:

int resourceId = getResources().getIdentifier("imagename", "drawable", "mypackage");
// get bitmap from resource id
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), resourceId);
StackBlurManager stackBlurManager = new StackBlurManager(bitmap);
// process the image using a certain radius
stackBlurManager.process(progress*4);
// obtain the image and load it into an ImageView or any other component
imgLock.setImageBitmap(stackBlurManager.returnBlurredImage());

当我导入StackBlur项目时,Eclipse会给我这个错误提示:“无法解析sdk.buildtools属性值'18.1.0' - 未知的Android构建工具问题”。我该如何解决? - aletede91
您可以从Android SDK管理器中安装它。在“工具”部分,您将找到Android Build Tools,只需安装“18.1.0”版本即可。 - Ahmed Hegazy
我已经安装了,但是现在出现了新的错误:“RenderScript支持模式需要Build-Tools 19.0.3或更高版本。” - aletede91
似乎是在 https://github.com/kikoso/android-stackblur/issues/22 的库中出现了问题。你应该将 Android Build Tools 更改为最新版本。 - Ahmed Hegazy

0

现在有点晚了,但我在尝试加载后直接使用bitmaptransfrom时遇到了错误。如果你也遇到了同样的问题,请使用:

Glide.with(mContext).load(drawable).apply(RequestOptions.bitmapTransform(new BlurTransformation())).into(imageView);

0

该库可以使用RenderScript,因此模糊处理速度快,易于使用:

<ru.egslava.blurredview.BlurredImageView
    ...
    android:src="@drawable/..."
    app:radius="0.3"
    app:keepOriginal="true"
    app:downSampling="2" />

0

添加依赖项

compile 'jp.wasabeef:fresco-processors:2.1.0'

在布局文件中使用以下代码:

<com.facebook.drawee.view.SimpleDraweeView
   android:id="@+id/imageView"
   android:layout_width="match_parent"
   android:layout_height="match_parent"/>

在你的Java文件中使用以下代码:

SimpleDraweeView imgView = (SimpleDraweeView) findViewById(R.id.imageView);
            ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri)
                    .setPostprocessor(new IterativeBoxBlurPostProcessor(20))
                    .build();
            DraweeController controller = Fresco.newDraweeControllerBuilder()
                    .setImageRequest(request)
                    .setOldController(imgView.getController())
                    .build();
            imgView.setController(controller);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接