11package com .omarea .common .ui ;
22
33import android .app .Activity ;
4- import android .app .WallpaperManager ;
5- import android .content .Context ;
64import android .graphics .Bitmap ;
7- import android .graphics .BitmapFactory ;
85import android .graphics .Canvas ;
96import android .graphics .ColorMatrix ;
107import android .graphics .ColorMatrixColorFilter ;
118import android .graphics .Paint ;
129import android .graphics .Rect ;
13- import android .graphics .drawable .BitmapDrawable ;
14- import android .graphics .drawable .Drawable ;
1510import android .view .View ;
1611
17- import com .tool .tree .ThemeConfig ; //
18-
19- import java .io .File ;
20-
2112public class FastBlurUtility {
2213
23- // Tỉ lệ thu nhỏ ảnh để xử lý nhanh (giúp giảm tải cho CPU )
14+ // Tỉ lệ thu nhỏ ảnh để xử lý nhanh (1/10 giúp giảm 100 lần số pixel cần tính toán )
2415 private static final float SCALE_FACTOR = 0.10f ;
25- private static final int BLUR_RADIUS = 15 ;
26-
27- // Lưu vết để nhận diện thay đổi file
28- private static long lastFileLength = -1 ;
29- private static long lastFileModified = -1 ;
16+ private static final int BLUR_RADIUS = 8 ;
3017
3118 /**
32- * Quy trình chính: Kiểm tra ThemeMode -> Chọn nguồn ảnh -> Làm mờ
19+ * Chụp màn hình và làm mờ (Dùng làm phương án dự phòng khi không lấy được Wallpaper)
3320 */
3421 public static Bitmap getBlurBackgroundDrawer (Activity activity ) {
35- ThemeConfig themeConfig = new ThemeConfig (activity );
36- int mode = themeConfig .getThemeMode (); //
37-
38- Bitmap sourceBmp = null ;
39-
40- // 1. Nếu Mode >= 3: Tắt chụp màn hình, ưu tiên lấy từ file hoặc Wallpaper hệ thống
41- if (mode >= 3 ) {
42- sourceBmp = getCustomWallpaper (activity );
43-
44- if (sourceBmp == null ) {
45- sourceBmp = getSystemWallpaper (activity );
46- }
47- }
48-
49- // 2. Nếu Mode < 3 hoặc không lấy được ảnh nền: Dùng phương án chụp màn hình
50- if (sourceBmp == null ) {
51- sourceBmp = takeScreenShot (activity );
52- }
53-
54- return startBlurBackground (sourceBmp );
55- }
56-
57- /**
58- * Kiểm tra và lấy ảnh từ file custom: home/etc/wallpaper.jpg
59- */
60- private static Bitmap getCustomWallpaper (Context context ) {
61- File file = new File (context .getFilesDir (), "home/etc/wallpaper.jpg" );
62- if (file .exists ()) {
63- long currentLength = file .length ();
64- long currentModified = file .lastModified ();
65-
66- // Cập nhật thông tin file để nhận diện thay đổi lần sau
67- lastFileLength = currentLength ;
68- lastFileModified = currentModified ;
69-
70- return BitmapFactory .decodeFile (file .getAbsolutePath ());
71- }
72- return null ;
73- }
74-
75- /**
76- * Lấy hình nền mặc định của hệ thống
77- */
78- private static Bitmap getSystemWallpaper (Context context ) {
79- try {
80- WallpaperManager wm = WallpaperManager .getInstance (context );
81- Drawable drawable = wm .getDrawable ();
82- if (drawable instanceof BitmapDrawable ) {
83- return ((BitmapDrawable ) drawable ).getBitmap ();
84- }
85- } catch (Exception e ) {
86- e .printStackTrace ();
87- }
88- return null ;
22+ Bitmap bmp = takeScreenShot (activity );
23+ return startBlurBackground (bmp );
8924 }
9025
9126 /**
92- * Quy trình xử lý: Thu nhỏ -> Làm mờ -> Phóng to & Nhuộm tối
27+ * Quy trình xử lý: Thu nhỏ -> Làm mờ -> Phóng to & Nhuộm tối (Dim)
28+ * Đảm bảo mượt mà từ SDK 23 trở lên.
9329 */
9430 public static Bitmap startBlurBackground (Bitmap bkg ) {
9531 if (bkg == null || bkg .isRecycled ()) return null ;
9632
33+ // 1. Tính toán kích thước thu nhỏ
9734 int width = Math .round (bkg .getWidth () * SCALE_FACTOR );
9835 int height = Math .round (bkg .getHeight () * SCALE_FACTOR );
9936
10037 if (width <= 0 || height <= 0 ) return bkg ;
10138
102- // Thu nhỏ để tối ưu hiệu năng
39+ // 2. Thu nhỏ ảnh (Sử dụng bộ lọc Bilinear để ảnh mượt hơn)
10340 Bitmap smallBitmap = Bitmap .createScaledBitmap (bkg , width , height , true );
10441
105- // Làm mờ bằng thuật toán StackBlur
42+ // 3. Làm mờ bằng thuật toán StackBlur (CPU-based, cực kỳ ổn định)
10643 Bitmap blurred = fastBlur (smallBitmap , BLUR_RADIUS );
10744
108- // Phóng to về kích thước gốc và áp dụng bộ lọc màu tối (Dim)
45+ // 4. Phóng to về kích thước gốc và áp dụng bộ lọc màu tối
10946 return scaleAndDim (blurred , bkg .getWidth (), bkg .getHeight ());
11047 }
11148
49+ /**
50+ * Chụp ảnh màn hình an toàn trên SDK 23+
51+ */
11252 private static Bitmap takeScreenShot (Activity activity ) {
11353 try {
11454 View view = activity .getWindow ().getDecorView ();
@@ -123,13 +63,17 @@ private static Bitmap takeScreenShot(Activity activity) {
12363 }
12464 }
12565
66+ /**
67+ * Phóng to ảnh và áp dụng ColorMatrix để làm tối nền (Dim)
68+ */
12669 private static Bitmap scaleAndDim (Bitmap bitmap , int targetW , int targetH ) {
12770 Bitmap output = Bitmap .createBitmap (targetW , targetH , Bitmap .Config .ARGB_8888 );
12871 Canvas canvas = new Canvas (output );
12972
73+ // Paint với bộ lọc chống răng cưa và lọc bitmap khi scale
13074 Paint paint = new Paint (Paint .FILTER_BITMAP_FLAG | Paint .ANTI_ALIAS_FLAG );
13175
132- // Làm tối nền (contrast 0.80f giúp nội dung Drawer nổi bật hơn )
76+ // Tạo bộ lọc màu để giảm độ sáng (contrast 0.85f ~ giảm 15% độ sáng )
13377 ColorMatrix cm = new ColorMatrix ();
13478 float contrast = 0.80f ;
13579 cm .set (new float []{
@@ -139,10 +83,12 @@ private static Bitmap scaleAndDim(Bitmap bitmap, int targetW, int targetH) {
13983 0 , 0 , 0 , 1 , 0 });
14084 paint .setColorFilter (new ColorMatrixColorFilter (cm ));
14185
86+ // Vẽ ảnh từ vùng nguồn (nhỏ) ra vùng đích (toàn màn hình)
14287 Rect src = new Rect (0 , 0 , bitmap .getWidth (), bitmap .getHeight ());
14388 Rect dst = new Rect (0 , 0 , targetW , targetH );
14489 canvas .drawBitmap (bitmap , src , dst , paint );
14590
91+ // Giải phóng bitmap tạm sau khi đã vẽ xong
14692 if (bitmap != null && !bitmap .isRecycled ()) {
14793 bitmap .recycle ();
14894 }
@@ -151,10 +97,10 @@ private static Bitmap scaleAndDim(Bitmap bitmap, int targetW, int targetH) {
15197 }
15298
15399 /**
154- * Thuật toán StackBlur
100+ * Thuật toán StackBlur (Multi-pass box blur) - Tối ưu cho hiệu năng CPU
101+ * Hỗ trợ hoàn hảo cho các thiết bị từ cũ đến mới.
155102 */
156103 private static Bitmap fastBlur (Bitmap sentBitmap , int radius ) {
157- if (sentBitmap == null || sentBitmap .isRecycled ()) return null ;
158104 Bitmap bitmap = sentBitmap .copy (sentBitmap .getConfig (), true );
159105
160106 if (radius < 1 ) return null ;
@@ -241,9 +187,9 @@ private static Bitmap fastBlur(Bitmap sentBitmap, int radius) {
241187 bsum += binsum ;
242188 stackpointer = (stackpointer + 1 ) % div ;
243189 sir = stack [(stackpointer ) % div ];
244- routsum - = sir [0 ];
245- goutsum - = sir [1 ];
246- boutsum - = sir [2 ];
190+ routsum + = sir [0 ];
191+ goutsum + = sir [1 ];
192+ boutsum + = sir [2 ];
247193 rinsum -= sir [0 ];
248194 ginsum -= sir [1 ];
249195 binsum -= sir [2 ];
@@ -300,9 +246,9 @@ private static Bitmap fastBlur(Bitmap sentBitmap, int radius) {
300246 bsum += binsum ;
301247 stackpointer = (stackpointer + 1 ) % div ;
302248 sir = stack [stackpointer ];
303- routsum - = sir [0 ];
304- goutsum - = sir [1 ];
305- boutsum - = sir [2 ];
249+ routsum + = sir [0 ];
250+ goutsum + = sir [1 ];
251+ boutsum + = sir [2 ];
306252 rinsum -= sir [0 ];
307253 ginsum -= sir [1 ];
308254 binsum -= sir [2 ];
0 commit comments