【问题标题】:How to blur background images in Android如何在Android中模糊背景图像
【发布时间】:2015-07-26 21:08:26
【问题描述】:

像下图这样模糊背景图像的最佳方法是什么?我看到了一些代码和库,但它们已经有几年历史了,或者像 BlurBehind 库一样,但它并没有产生相同的效果。提前致谢!

【问题讨论】:

  • 大多数人只是自己动手或使用现有的库。这就是我的建议。您可以很容易地在线找到快速的框模糊实现。或者,如果您没有为模糊设置动画,则只需预渲染您的模糊图像。
  • 你看过这个:stackoverflow.com/questions/6795483/…?对我来说就像一个魅力
  • 有两种实现方式。 1)您可以使用可以设置模糊背景的 FrameLayout。 2)你可以使用我最新的 Blur 库!
  • 感谢@StephenG 的回答对我帮助很大。
  • 人们可能需要的 Kotlin 版本:在 Github 上查看此存储库

标签: java android


【解决方案1】:

最简单的方法是使用库。看看这个:https://github.com/wasabeef/Blurry

有了这个库,你只需要这样做:

Blurry.with(context)
  .radius(10)
  .sampling(8)
  .color(Color.argb(66, 255, 255, 0))
  .async()
  .onto(rootView);

【讨论】:

  • 我看到这个库是“github 中的趋势”......但我不知道是否只是截图(我还没有尝试过)但截图有点像素化.
  • 我认为这与描述图像是 Gif 的事实有关。您应该尝试一下,它应该可以正常工作。
  • 抱歉,使用您的样本没有任何效果,我什至弄乱了值,但什么也没发生
  • 兄弟什么是 rootView.. 当我将 ImageView 设置到它上面时显示错误
  • 它不起作用。这个样本根本不起作用(奇怪)。然后我从他们的仓库中尝试了样本,只有白色图像.. :(
【解决方案2】:

这是一种使用我在article 上找到的 Android 的 RenderScript 有效地模糊图像的简单方法

  1. 创建一个名为 BlurBuilder 的类

    public class BlurBuilder {
      private static final float BITMAP_SCALE = 0.4f;
      private static final float BLUR_RADIUS = 7.5f;
    
      public static Bitmap blur(Context context, Bitmap image) {
        int width = Math.round(image.getWidth() * BITMAP_SCALE);
        int height = Math.round(image.getHeight() * BITMAP_SCALE);
    
        Bitmap inputBitmap = Bitmap.createScaledBitmap(image, width, height, false);
        Bitmap outputBitmap = Bitmap.createBitmap(inputBitmap);
    
        RenderScript rs = RenderScript.create(context);
        ScriptIntrinsicBlur theIntrinsic = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
        Allocation tmpIn = Allocation.createFromBitmap(rs, inputBitmap);
        Allocation tmpOut = Allocation.createFromBitmap(rs, outputBitmap);
        theIntrinsic.setRadius(BLUR_RADIUS);
        theIntrinsic.setInput(tmpIn);
        theIntrinsic.forEach(tmpOut);
        tmpOut.copyTo(outputBitmap);
    
        return outputBitmap;
      }
    }
    
  2. 将任何图像复制到您的可绘制文件夹

  3. 像这样在您的活动中使用 BlurBuilder:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.activity_login);
    
        mContainerView = (LinearLayout) findViewById(R.id.container);
        Bitmap originalBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.background);
        Bitmap blurredBitmap = BlurBuilder.blur( this, originalBitmap );
        mContainerView.setBackground(new BitmapDrawable(getResources(), blurredBitmap));
    
  4. Renderscript 包含在支持 v8 中,可以将此答案降至 api 8。要使用 gradle 启用它,请将这些行包含到您的 gradle 文件中(来自此 answer

    defaultConfig {
        ...
        renderscriptTargetApi *your target api*
        renderscriptSupportModeEnabled true
    }
    
  5. 结果

【讨论】:

  • 感谢您的回答,我只想补充一点,此解决方案需要 API 19,以启用支持 API 8 的支持库,请参阅此答案stackoverflow.com/a/22976675/5519369
  • 如果我们想增加模糊能力怎么办?改变什么
  • @Sam 将BLUR_RADIUS 设置为您想要的值。
  • 如果我更改 BITMAP_SCALE 值会怎样?
【解决方案3】:

你可以使用:

Glide.with(getContext()).load(R.mipmap.bg)
     .apply(bitmapTransform(new BlurTransformation(22)))
     .into((ImageView) view.findViewById(R.id.imBg));

这需要在您的build.gradle 文件中添加以下内容:

implementation 'jp.wasabeef:glide-transformations:4.0.0'

【讨论】:

  • 对于那些遇到BlurTransformation 未解决的参考错误的人,您需要将此implementation 'jp.wasabeef:glide-transformations:4.0.0 添加到您的gradle 中
  • 它可以工作,但是这个看起来不干净。如果您想要有雾的感觉,请使用其他模块。这一个显示出强大的边缘。只是内部是模糊的。
  • 第三方库依赖应添加到答案中,而不是注释中。
【解决方案4】:

下面给出了实现这一点的最简单方法,

我)

Glide.with(context.getApplicationContext())
                        .load(Your Path)   
                        .override(15, 15) // (change according to your wish)
                        .error(R.drawable.placeholder)
                        .into(image.score);

否则你可以按照下面的代码..

二)

1.创建一个类。(代码如下)

public class BlurTransformation extends BitmapTransformation {

    private RenderScript rs;

    public BlurTransformation(Context context) {
        super( context );

        rs = RenderScript.create( context );
    }

    @Override
    protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
        Bitmap blurredBitmap = toTransform.copy( Bitmap.Config.ARGB_8888, true );

        // Allocate memory for Renderscript to work with
        Allocation input = Allocation.createFromBitmap(
            rs, 
            blurredBitmap, 
            Allocation.MipmapControl.MIPMAP_FULL, 
            Allocation.USAGE_SHARED
        );
        Allocation output = Allocation.createTyped(rs, input.getType());

        // 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(10);

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

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

        toTransform.recycle();

        return blurredBitmap;
    }

    @Override
    public String getId() {
        return "blur";
    }
}

2.使用 Glide 将图像设置为 ImageView。

例如:

Glide.with(this)
     .load(expertViewDetailsModel.expert.image)
     .asBitmap()
     .transform(new BlurTransformation(this))
     .into(ivBackground);

【讨论】:

    【解决方案5】:

    Android 12,Preview 1 带有内置的模糊功能。我们现在不需要依赖外部库。这是代码

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

    【讨论】:

    • 如何使用窗口背景模糊?我的测试不起作用。
    • 我怀疑我们应该使用RenderScript,否则无法编译。
    【解决方案6】:

    这可能不是最有效的解决方案,但我不得不使用它,因为 wasabeef/Blurry 库不适合我。如果您打算制作一些模糊动画,这可能会很方便:

    1- 你需要有 2 个版本的图片,正常的一个和你用 photoshop 或其他任何东西制作的模糊的一个

    2- 在您的 xml 中将图像设置为彼此适合,然后可以看到其中一个,那就是上面的一个

    3-在上面设置淡出动画:

    final Animation fadeOut = new AlphaAnimation(1, 0);
            fadeOut.setInterpolator(new AccelerateInterpolator());
            fadeOut.setDuration(1000);
    
    
            fadeOut.setAnimationListener(new Animation.AnimationListener() {
                @Override
                public void onAnimationStart(Animation animation) {}
    
                @Override
                public void onAnimationEnd(Animation animation) {upperone.setVisibility(View.GONE);}
    
                @Override
                public void onAnimationRepeat(Animation animation) {}
            });
    
            upperone.startAnimation(fadeOut);
    

    【讨论】:

      【解决方案7】:

      您可以使用 Glide 加载并转换为模糊图像, 1) 只有一个视图,

      val requestOptions = RequestOptions()
                      requestOptions.transform(BlurTransformation(50)) // 0-100
      Glide.with(applicationContext).setDefaultRequestOptions(requestOptions)
                              .load(imageUrl).into(view)
      

      2) 如果您使用适配器在项目中加载图像,则应在 if-else 块中编写代码,否则会使您的所有图像模糊。

       if(isBlure){
        val requestOptions = RequestOptions()
                      requestOptions.transform(BlurTransformation(50))
                      Glide.with(applicationContext).setDefaultRequestOptions(requestOptions)
                              .load(imageUrl).into(view )
      }else{
       val requestOptions = RequestOptions()
                  Glide.with(applicationContext).setDefaultRequestOptions(requestOptions).load(imageUrl).into(view)
      }
      

      【讨论】:

        【解决方案8】:

        目前仅适用于 Android 12,因此还不是通用解决方案

        模糊图像

        1 在 build.gradle 中设置你的目标 SDK 并将 SDK 编译为 Android S

        2.使用Render Effect

        3.设置模糊如下

        your_view.setRenderEffect(
             RenderEffect.createBlurEffect(
             30f, //radius X
             30f, //Radius Y
             Shader.TileMode.[X]// X=CLAMP,DECAL,MIRROR,REPEAT
        )
        

        4.4种混合模式是

        CLAMP- 如果着色器在其原始边界之外绘制,则复制边缘颜色

        DECAL- 仅在其原始边界内渲染着色器的图像像素

        MIRROR- 水平和垂直重复着色器的图像,交替镜像,以便相邻图像始终接缝。

        REPEAT - 水平和垂直重复着色器的图像。

        【讨论】:

          【解决方案9】:

          您可以有一个背景颜色为黑色的视图,并将该视图的 alpha 设置为 0.7 或根据您的要求设置任何值。

          <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:background="@drawable/onboardingimg1">
              <View
                  android:id="@+id/opacityFilter"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent"
                  android:background="@android:color/black"
                  android:layout_alignParentBottom="true"
                  android:alpha="0.7">
              </View>
          
          
          </RelativeLayout>
          

          【讨论】:

          • 它不会产生与模糊相同的效果
          • 此外,这会模糊作为子项添加的文本视图。
          • 模糊效果不同于不透明效果。
          【解决方案10】:

          试试下面的代码.. 将此代码放入 On Create..

           if (android.os.Build.VERSION.SDK_INT > 9) {
                      StrictMode.ThreadPolicy policy =
                              new StrictMode.ThreadPolicy.Builder().permitAll().build();
                      StrictMode.setThreadPolicy(policy);
                  }
                 Url="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTIur0ueOsmVmFVmAA-SxcCT7bTodZb3eCNbiShIiP9qWCWk3mDfw";
          //        Picasso.with(getContext()).load(Url).into(img_profile);
          //        Picasso.with(getContext()).load(Url).into(img_c_profile);
          
                  bitmap=getBitmapFromURL(Url);
                  Bitmap blurred = blurRenderScript(bitmap, 12);//second parametre is radius
                  img_profile.setImageBitmap(blurred);
          

          创建下面的方法..只需复制过去..

           public static Bitmap getBitmapFromURL(String src) {
                  try {
                      URL url = new URL(src);
                      HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                      connection.setDoInput(true);
                      connection.connect();
                      InputStream input = connection.getInputStream();
                      Bitmap myBitmap = BitmapFactory.decodeStream(input);
                      return myBitmap;
                  } catch (IOException e) {
                      // Log exception
                      return null;
                  }
              }
              @SuppressLint("NewApi")
              private Bitmap blurRenderScript(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(getActivity());
          
                  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 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;
              }
          

          【讨论】:

            【解决方案11】:

            这可能是一个很晚的回复,但我希望它对某人有所帮助。

            1. 您可以使用第三方库,例如 RenderScript/Blurry/等。
            2. 如果您不想使用任何第三方库,可以使用 alpha 执行以下操作(将 alpha 设置为 0 表示完全模糊,1 表示与现有相同)。

            注意(如果您使用第 2 点) :将 alpha 设置为背景时,会模糊整个布局。为避免这种情况,创建一个包含可绘制对象的新 xml,并将此处的 alpha 设置为 0.5(或您希望的值),并使用此可绘制对象名称(文件名)作为背景。

            例如,如下使用它(比如文件名为 bgndblur.xml):

            <bitmap xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:shape="rectangle"
            android:src="@drawable/registerscreenbackground" 
            android:alpha="0.5">
            

            在您的布局中使用以下内容:

            <....
             android:background="@drawable/bgndblur">
            

            希望这会有所帮助。

            【讨论】:

            • 这不是模糊的。
            【解决方案12】:

            您可以通过以下操作快速获得模糊效果。

            // 将此添加到 build.gradle app //

            Compile ' com.github.jgabrielfreitas:BlurImageView:1.0.1 '
            

            // 添加到 XML

            <com.jgbrielfreitas.core.BlurImageView
                android:id="@+id/iv_blur_image"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
            />
            

            //将这个添加到java中

            Import com.jgabrielfreitas.core.BlueImageView;
            

            //公共类下*活动名称* //

            BlurImageView myBlurImage;
            

            // Oncreate 下//

            myBlurImage = (ImageView) findViewById(R.id.iv_blur_image)
            MyBlurImage.setBlue(5)
            

            希望对大家有所帮助

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2015-05-26
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-07-30
              • 1970-01-01
              • 2016-11-16
              • 2013-09-11
              相关资源
              最近更新 更多