簡體   English   中英

如何在 Android 中模糊背景圖像

[英]How to blur background images in Android

像下圖這樣模糊背景圖像的最佳方法是什么? 我看到了一些代碼和庫,但它們已經有幾年的歷史了,或者像 BlurBehind 庫,但它並沒有產生同樣的效果。

在此處輸入圖像描述

最簡單的方法是使用庫。 看看這個: https : //github.com/wasabeef/Blurry

使用庫,您只需要執行以下操作:

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

這是使用我在本文中找到的 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 文件中(來自這個答案

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

在此處輸入圖片說明

您可以使用:

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'

下面給出了實現此目的的最簡單方法,

一世)

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);

overlay是位於視圖(“主視圖”)上方的一個額外層,該視圖是在該視圖中所有其他內容(包括子視圖,如果視圖是ViewGroup)之后繪制的。 與覆蓋層的交互是通過添加和刪除可繪制對象來完成的。 試試看, 用用戶說明覆蓋

這對我有用。 在 Android 9 和 12 上測試。使用 Glide 庫縮小位圖。

// Glide
implementation 'com.github.bumptech.glide:glide:4.13.0'
kapt 'com.github.bumptech.glide:compiler:4.13.0'
Glide.with(context).asBitmap().load(favorite.coverImage).into(object : CustomTarget<Bitmap>(2, 2) {
                    override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
                        ivContentHolder.setImageDrawable(BitmapDrawable(itemBinding.root.context.resources, resource))
                    }

                    override fun onLoadCleared(placeholder: Drawable?) {
                        ivContentHolder.setImageDrawable(null)
                    }

CustomTarget(2, 2) 是訣竅。 值越低,模糊效果越強。 基本上它用於縮小圖像尺寸。 然后你所要做的就是將縮小的位圖設置到你的 imageView 中。 最重要的是將 imageView 的 ScaleType 設置為 CenterCrop。

<ImageView
                android:id="@+id/iv_content_holder"
                android:layout_width="match_parent"
                android:layout_height="96dp"
                android:scaleType="centerCrop"
                android:src="@color/purple_700"
                app:layout_constraintBottom_toBottomOf="parent" />

結果看起來像這樣。 模糊效果演示iOS 類似模糊效果

這可能不是最有效的解決方案,但我不得不使用它,因為 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);

試試下面的代碼..把這個代碼放在創建中..

 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;
    }

您可以使用 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)
}

Android 12, Preview 1 帶有內置模糊功能。 我們現在不需要依賴外部庫。 這是代碼

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

目前僅適用於 Android 12,因此還不是通用解決方案

模糊圖像

1 在 build.gradle 中設置目標 SDK 並編譯 SDK 到 Android S

2.使用渲染效果

3.設置模糊如下

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

4.混合模式的4種類型是

CLAMP-如果着色器繪制在其原始邊界之外,則復制邊緣顏色

貼花 - 僅在其原始邊界內渲染着色器的圖像像素

鏡像 - 水平和垂直重復着色器的圖像,交替鏡像,以便相鄰圖像始終接縫。

REPEAT - 水平和垂直重復着色器的圖像。

Android 12 (Api level 31) 新增 Theme 參數,用於申請 windows 模糊背景:

<style name="BlurryTheme" parent="...">
    <item name="android:windowBackgroundBlurRadius">30dp</item>
    <item name="android:windowBlurBehindEnabled">true</item>
    <item name="android:windowBlurBehindRadius">10dp</item>
</style>

還有用於View應用模糊效果的新 API android.view.View#setRenderEffect

imageView.setRenderEffect(
    RenderEffect.createBlurEffect(
        20.0f, 20.0f, Shader.TileMode.CLAMP
    )
)

您可以將視圖的背景顏色設置為黑色,並將視圖的 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>

這可能是一個很晚的回復,但我希望它可以幫助某人。

  1. 您可以使用第三方庫,例如 RenderScript/Blurry/等。
  2. 如果您不想使用任何第三方庫,您可以使用 alpha 執行以下操作(將 alpha 設置為 0 表示完全模糊,1 表示與現有相同)。

注意(如果您使用第 2 點) :將 alpha 設置為背景時,它會模糊整個布局。 為避免這種情況,請創建一個包含 drawable 的新 xml,並將此處的 alpha 設置為 0.5(或您希望的值),並使用此 drawable 名稱(文件名)作為背景。

例如,如下使用它(假設文件名為 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">

希望這有幫助。

您可以通過執行以下操作快速獲得模糊效果。

// 將此添加到 build.gradle 應用程序 //

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)

我希望能幫助某人

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM