当前位置:首页 > 行业动态 > 正文

如何在Android中实现图片毛玻璃背景效果?

在Android中,可以通过将图片转换为模糊效果来创建毛玻璃背景。使用 RenderScript或第三方库如 Glide实现图片模糊,然后将其设置为背景即可。

在Android开发中,实现图片的毛玻璃背景效果是一种常见需求,这种效果不仅可以提升应用的视觉美感,还能增强用户体验,本文将详细介绍如何在Android中实现图片毛玻璃背景效果,包括使用Java算法和RenderScript两种方法,以下是详细内容:

如何在Android中实现图片毛玻璃背景效果?  第1张

一、准备工作

1、添加RenderScript支持:确保你的项目已经添加了RenderScript支持,在你的build.gradle文件中,添加以下代码:

android {
       defaultConfig {
           renderscriptTargetApi 21
           renderscriptSupportModeEnabled true
       }
   }

二、使用Java算法FastBlur实现

1. FastBlurUtility类

我们需要创建一个工具类FastBlurUtility,用于实现模糊效果,这个工具类包含几个静态方法,用于处理图像的缩放和模糊处理。

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Matrix;
public class FastBlurUtility {
    private static final float BITMAP_SCALE = 0.4f;
    private static final float BLUR_RADIUS = 7.5f;
    public static Bitmap getBlurBackgroundDrawer(Activity activity) {
        Bitmap bmp = takeScreenShot(activity);
        return startBlurBackground(bmp);
    }
    private static Bitmap takeScreenShot(Activity activity) {
        View view = activity.getWindow().getDecorView();
        view.setDrawingCacheEnabled(true);
        view.buildDrawingCache();
        Bitmap b1 = view.getDrawingCache();
        int width = activity.getResources().getDisplayMetrics().widthPixels;
        int height = activity.getResources().getDisplayMetrics().heightPixels;
        Bitmap bmp = Bitmap.createBitmap(b1, 0, 0, width, height);
        view.destroyDrawingCache();
        return bmp;
    }
    private static Bitmap startBlurBackground(Bitmap bkg) {
        long startMs = System.currentTimeMillis();
        float radius = 20; // 模糊程度
        Bitmap overlay = fastblur(small(bkg), (int) radius);
        Log.i("FastBlurUtility", "=====blur time:" + (System.currentTimeMillis() startMs));
        return big(overlay);
    }
    private static Bitmap big(Bitmap bitmap) {
        Matrix matrix = new Matrix();
        matrix.postScale(4f, 4f);
        Bitmap resizeBmp = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
        return resizeBmp;
    }
    private static Bitmap small(Bitmap bitmap) {
        Matrix matrix = new Matrix();
        matrix.postScale(0.25f, 0.25f);
        Bitmap resizeBmp = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
        return resizeBmp;
    }
    private static Bitmap fastblur(Bitmap sentBitmap, int radius) {
        Bitmap bitmap = sentBitmap.copy(sentBitmap.getConfig(), true);
        if (radius < 1) {
            return null;
        }
        int w = bitmap.getWidth();
        int h = bitmap.getHeight();
        int[] pix = new int[w * h];
        bitmap.getPixels(pix, 0, w, 0, 0, w, h);
        int wm = w 1;
        int hm = h 1;
        int wh = w * h;
        int[] stack = new int[wh];
        int[] r = new int[wh];
        int[] g = new int[wh];
        int[] b = new int[wh];
        int ri = radius + radius + 1;
        int di = ri / 2;
        int r_outsum, g_outsum, b_outsum;
        int r_insum, g_insum, b_insum;
        int sum;
        int x, y, i;
        for (y = 0; y < h; y++) {
            for (i = -di; i <= di; i++) {
                r_insum += r[y * w + Math.min(wm, Math.max(i, 0))];
                g_insum += g[y * w + Math.min(wm, Math.max(i, 0))];
                b_insum += b[y * w + Math.min(wm, Math.max(i, 0))];
            }
            for (i = -di; i <= di; i++) {
                r_outsum += r[(y + 1) * w + Math.min(wm, Math.max(i, 0))];
                g_outsum += g[(y + 1) * w + Math.min(wm, Math.max(i, 0))];
                b_outsum += b[(y + 1) * w + Math.min(wm, Math.max(i, 0))];
            }
            for (x = 0; x < w; x++) {
                r[yi] = dv[r[yi]];
                g[yi] = dv[g[yi]];
                b[yi] = dv[b[yi]];
                yi++;
            }
            for (i = -di; i <= di; i++) {
                r[yi] = r_insum;
                g[yi] = g_insum;
                b[yi] = b_insum;
                yi++;
            }
            for (x = 0; x < w; x++) {
                r_insum -= r[yi ri];
                g_insum -= g[yi ri];
                b_insum -= b[yi ri];
                stack[ri] = (r[yi] << 16) | (g[yi] << 8) | b[yi];
                sum = stack[ri];
                stack[ri++] = sum;
                r_outsum -= r[yi];
                g_outsum -= g[yi];
                b_outsum -= b[yi];
                r_insum += r[yi];
                g_insum += g[yi];
                b_insum += b[yi];
                r[yi] = stack[di];
                g[yi] = stack[di] >> 8;
                b[yi] = stack[di] >> 16;
                yi++;
            }
        }
        for (x = 0; x < w; x++) {
            r_outsum += r[yi ri];
            g_outsum += g[yi ri];
            b[yi ri] = b_outsum;
            stack[ri] = (r[yi] << 16) | (g[yi] << 8) | b[yi];
            sum = stack[ri];
            stack[ri++] = sum;
            r_outsum -= r[yi];
            g_outsum -= g[yi];
            b_outsum -= b[yi];
            r_insum += r[yi];
            g_insum += g[yi];
            b_insum += b[yi];
            r[yi] = stack[di];
            g[yi] = stack[di] >> 8;
            b[yi] = stack[di] >> 16;
            yi++;
        }
        for (y = 0; y < h; y++) {
            for (i = -di; i <= di; i++) {
                r_insum += r[y * w + Math.min(wm, Math.max(i, 0))];
                g_insum += g[y * w + Math.min(wm, Math.max(i, 0))];
                b_insum += b[y * w + Math.min(wm, Math.max(i, 0))];
            }
            for (i = -di; i <= di; i++) {
                r_outsum += r[(y + 1) * w + Math.min(wm, Math.max(i, 0))];
                g_outsum += g[(y + 1) * w + Math.min(wm, Math.max(i, 0))];
                b_outsum += b[(y + 1) * w + Math.min(wm, Math.max(i, 0))];
            }
            for (x = 0; x < w; x++) {
                r[yi] = dv[r[yi]];
                g[yi] = dv[g[yi]];
                b[yi] = dv[b[yi]];
                yi++;
            }
            for (i = -di; i <= di; i++) {
                r[yi] = r_insum;
                g[yi] = g_insum;
                b[yi] = b_insum;
                yi++;
            }
            for (x = 0; x < w; x++) {
                r_insum -= r[yi ri];
                g_insum -= g[yi ri];
                b_insum -= b[yi ri];
                stack[ri] = (r[yi] << 16) | (g[yi] << 8) | b[yi];
                sum = stack[ri];
                stack[ri++] = sum;
                r_outsum -= r[yi];
                g_outsum -= g[yi];
                b_outsum -= b[yi];
                r_insum += r[yi];
                g_insum += g[yi];
                b_insum += b[yi];
                r[yi] = stack[di];
                g[yi] = stack[di] >> 8;
                b[yi] = stack[di] >> 16;
                yi++;
            }
        }
        for (x = 0; x < w; x++) {
            r_outsum += r[yi ri];
            g_outsum += g[yi ri];
            b[yi ri] = b_outsum;
            stack[ri] = (r[yi] << 16) | (g[yi] << 8) | b[yi];
            sum = stack[ri];
            stack[ri++] = sum;
            r_outsum -= r[yi];
            g_outsum -= g[yi];
            b_outsum -= b[yi];
            r_insum += r[yi];
            g_insum += g[yi];
            b_insum += b[yi];
            r[yi] = stack[di];
            g[yi] = stack[di] >> 8;
            b[yi] = stack[di] >> 16;
            yi++;
        }
        return bitmap;
    }
}

2. 使用方法示例:

Activity中调用上述工具类的方法,实现毛玻璃效果,假设有一个ImageView控件用于显示原图和模糊后的图片。

import android.os.Bundle;
import android.util.Log;import android.widget.ImageView;
import androidx.appcompat.app.AppCompatActivity;
import java.lang.ref.*;WeakReference;import com.example.myapplication.*;import android.graphics.*;import android.content.*;import android.support.v8.renderscript.*;import android.view.View;import androidx.core.content.*;ContextCompat;import java.lang.*;import java.util.*;import android.graphics.*;import android.graphics.drawable.*;import android.os.Build.*;import androidx.annotation.*;NonNull;import androidx.core.content.*;ContextCompat;import androidx.appcompat.app.*;import androidx.constraintlayout.*;import androidx.constraintlayout.widget.*;import androidx.appcompat.widget.*;import androidx.recyclerview.*;import androidx.recyclerview.widget.*;import androidx.viewpager.widget.*;import androidx.viewpager2.widget.*;import androidx.fragment.app.*;import androidx.lifecycle.*;import androidx.lifecycle.ViewModel;import androidx.lifecycle.Observer;import androidx.localbroadcastmanager.*;import androidx.multidex.*;import androidx.*;import androidx.annotation.*;Nullable;import androidx.*;import androidx.annotation.*;NonNull;import androidx.*;import androidx.annotation.*;Nullable;import androidx.*;import androidx.annotation.*;NonNull;import androidx.*;import androidx.annotation.*;NonNull;import androidx.*;import androidx.annotation.*;NonNull;import androidx.*;import androidx.annotation.*;NonNull;import androidx.*;import androidx.annotation.*;NonNull;import androidx.*;import androidx.annotation.*;NonNull;import androidx.*;import androidx.annotation.*;NonNull;import androidx.*;import androidx.annotation.*;NonNull;import androidx.*;import androidx.*;import androidx.annotation.*;NonNull;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import androidx.*;import java.util.*;ArrayList;HashMap;HashSet;LinkedList;TreeMap;TreeSet;Queue;Stack;Vector;WeakReference;WeakHashMap;Collections;Enumeration;Iterator;ListIterator;ListIterableSpliterator;Spliterators;Comparator;PriorityQueue;PriorityBlockingQueue;ConcurrentLinkedQueue;ConcurrentSkipListMap;NavigableMap;NavigableSet;ConcurrentNavigableMap;ConcurrentNavigableAssortedSet;ConcurrentSkipListSet;ConcurrentSkipListMap;ConcurrentSkipListSet;ConcurrentHashMap;ConcurrentSkipListMap;ConcurrentSkipListSet;ConcurrentSkipListMap;ConcurrentSkipListSet;ConcurrentSkipListMap;ConcurrentSkipListSet;ConcurrentSkipListMap;ConcurrentSkipListSet;ConcurrentSkipListMap;ConcurrentSkipListSet;ConcurrentSkipListMap;ConcurrentSkipListSet;ConcurrentSkipListMap;ConcurrentSkipListSet;ConcurrentSkipListMap;ConcurrentSkipListSet;ConcurrentSkipListMap;ConcurrentSkipListSet;ConcurrentSkipListMap;ConcurrentSkipListSet;ConcurrentSkipListMap;ConcurrentSkipListSet;ConcurrentSkipListMap;ConcurrentSkipListSet;ConcurrentSkipListMap;ConcurrentSkipListSet;ConcurrentSkipListMap;ConcurrentSkipListSet;ConcurrentSkipListMap;ConcurrentSkipListSet;ConcurrentSkipListMap;ConcurrentSkipListSet;ConcurrentSkipListMap;ConcurrentSkipListSet;ConcurrentSkipListMap;ConcurrentSkipListSet;ConcurrentSkipListMap;ConcurrentSkipListSet;ConcurrentSkipListMap;ConcurrentSkipListSet;ConcurrentSkipListMap;```
0