Skip to content

Commit f1beb48

Browse files
committed
Update
1 parent df97bbe commit f1beb48

1 file changed

Lines changed: 63 additions & 69 deletions

File tree

app/src/main/java/com/omarea/common/ui/FastBlurUtility.java

Lines changed: 63 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
import android.graphics.Canvas;
66
import android.graphics.ColorMatrix;
77
import android.graphics.ColorMatrixColorFilter;
8+
import android.graphics.Matrix;
89
import android.graphics.Paint;
9-
import android.graphics.Rect;
1010
import android.os.Handler;
1111
import android.os.Looper;
1212
import android.view.View;
@@ -16,10 +16,9 @@
1616

1717
public class FastBlurUtility {
1818

19-
private static final float SCALE_FACTOR = 0.10f;
19+
private static final float SCALE_FACTOR = 0.125f; // Thu nhỏ 8 lần (giống code cũ 0.10f)
2020
private static final int BLUR_RADIUS = 8;
2121

22-
// Executor để xử lý các tác vụ nặng ngoài UI Thread
2322
private static final ExecutorService executor = Executors.newSingleThreadExecutor();
2423
private static final Handler mainHandler = new Handler(Looper.getMainLooper());
2524

@@ -31,90 +30,89 @@ public interface BlurCallback {
3130
* Phương thức chính: Chụp và làm mờ không gây lag UI
3231
*/
3332
public static void getBlurBackgroundAsync(Activity activity, BlurCallback callback) {
34-
// 1. Chụp màn hình phải thực hiện trên UI Thread
35-
Bitmap screenshot = takeScreenShot(activity);
33+
// 1. Chụp màn hình ở dạng THU NHỎ ngay trên UI Thread (Rất nhanh, < 16ms)
34+
Bitmap smallBitmap = takeSmallScreenshot(activity);
3635

37-
if (screenshot == null) {
36+
if (smallBitmap == null) {
3837
callback.onBlurCompleted(null);
3938
return;
4039
}
4140

42-
// 2. Đẩy việc xử lý làm mờ vào Background Thread
41+
// 2. Đẩy việc xử lý nặng (Blur + Dim) vào Background Thread
4342
executor.execute(() -> {
44-
Bitmap blurred = startBlurProcess(screenshot);
43+
// Làm mờ trên ảnh nhỏ
44+
Bitmap blurred = fastBlur(smallBitmap, BLUR_RADIUS);
4545

46-
// 3. Trả kết quả về Main Thread qua Callback
47-
mainHandler.post(() -> callback.onBlurCompleted(blurred));
48-
});
49-
}
50-
51-
private static Bitmap startBlurProcess(Bitmap bkg) {
52-
if (bkg == null || bkg.isRecycled()) return null;
53-
54-
int originWidth = bkg.getWidth();
55-
int originHeight = bkg.getHeight();
56-
57-
// Tính toán kích thước thu nhỏ
58-
int width = Math.round(originWidth * SCALE_FACTOR);
59-
int height = Math.round(originHeight * SCALE_FACTOR);
60-
61-
if (width <= 0 || height <= 0) return bkg;
62-
63-
// Thu nhỏ ảnh
64-
Bitmap smallBitmap = Bitmap.createScaledBitmap(bkg, width, height, true);
65-
66-
// Giải phóng ảnh gốc ngay để tiết kiệm RAM
67-
if (bkg != smallBitmap) {
68-
bkg.recycle();
69-
}
70-
71-
// Làm mờ bằng thuật toán StackBlur
72-
Bitmap blurred = fastBlur(smallBitmap, BLUR_RADIUS);
46+
// Làm tối ảnh (giống getDimmedBitmap của code cũ)
47+
Bitmap dimmed = applyDim(blurred);
48+
49+
// Phóng to ảnh bằng Matrix (giống hàm big() của code cũ)
50+
Bitmap finalBitmap = upscale(dimmed);
7351

74-
// Phóng to và làm tối
75-
return scaleAndDim(blurred, originWidth, originHeight);
52+
// 3. Trả kết quả về Main Thread
53+
mainHandler.post(() -> callback.onBlurCompleted(finalBitmap));
54+
});
7655
}
7756

78-
private static Bitmap takeScreenShot(Activity activity) {
57+
/**
58+
* Chụp màn hình và thu nhỏ ngay lập tức để tiết kiệm RAM và CPU
59+
*/
60+
private static Bitmap takeSmallScreenshot(Activity activity) {
7961
try {
8062
View view = activity.getWindow().getDecorView();
81-
if (view.getWidth() <= 0 || view.getHeight() <= 0) return null;
63+
int width = view.getWidth();
64+
int height = view.getHeight();
65+
if (width <= 0 || height <= 0) return null;
66+
67+
// Tạo bitmap nhỏ ngay từ đầu
68+
int smallW = Math.round(width * SCALE_FACTOR);
69+
int smallH = Math.round(height * SCALE_FACTOR);
8270

83-
// Dùng RGB_565 để tiết kiệm 50% bộ nhớ so với ARGB_8888 (phù hợp SDK 23+)
84-
Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
71+
Bitmap bitmap = Bitmap.createBitmap(smallW, smallH, Bitmap.Config.ARGB_8888);
8572
Canvas canvas = new Canvas(bitmap);
73+
74+
// Scale canvas để khi view.draw nó tự thu nhỏ lại
75+
canvas.scale(SCALE_FACTOR, SCALE_FACTOR);
8676
view.draw(canvas);
77+
8778
return bitmap;
8879
} catch (Exception e) {
8980
return null;
9081
}
9182
}
9283

93-
private static Bitmap scaleAndDim(Bitmap bitmap, int targetW, int targetH) {
94-
Bitmap output = Bitmap.createBitmap(targetW, targetH, Bitmap.Config.ARGB_8888);
84+
/**
85+
* Làm tối ảnh (Thay thế getDimmedBitmap)
86+
*/
87+
private static Bitmap applyDim(Bitmap bitmap) {
88+
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
9589
Canvas canvas = new Canvas(output);
90+
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
9691

97-
Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG | Paint.ANTI_ALIAS_FLAG);
98-
99-
// Giảm độ sáng 20%
10092
ColorMatrix cm = new ColorMatrix();
101-
float contrast = 0.8f;
93+
float contrast = 0.80f; // Giảm độ sáng giống code cũ
10294
cm.setScale(contrast, contrast, contrast, 1.0f);
10395
paint.setColorFilter(new ColorMatrixColorFilter(cm));
104-
105-
Rect src = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
106-
Rect dst = new Rect(0, 0, targetW, targetH);
107-
canvas.drawBitmap(bitmap, src, dst, paint);
108-
109-
if (!bitmap.isRecycled()) {
110-
bitmap.recycle();
111-
}
112-
96+
97+
canvas.drawBitmap(bitmap, 0, 0, paint);
98+
bitmap.recycle();
11399
return output;
114100
}
115101

116102
/**
117-
* Thuật toán StackBlur tối ưu hóa
103+
* Phóng to ảnh (Thay thế hàm big())
104+
*/
105+
private static Bitmap upscale(Bitmap bitmap) {
106+
Matrix matrix = new Matrix();
107+
// Phóng to lại 8 lần (vì lúc đầu đã thu nhỏ 0.125)
108+
float scaleUp = 1f / SCALE_FACTOR;
109+
matrix.postScale(scaleUp, scaleUp);
110+
111+
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
112+
}
113+
114+
/**
115+
* Thuật toán StackBlur (Giữ nguyên từ code cũ của bạn)
118116
*/
119117
private static Bitmap fastBlur(Bitmap sentBitmap, int radius) {
120118
Bitmap bitmap = sentBitmap.copy(sentBitmap.getConfig(), true);
@@ -165,11 +163,9 @@ private static Bitmap fastBlur(Bitmap sentBitmap, int radius) {
165163
rsum += sir[0] * rbs;
166164
gsum += sir[1] * rbs;
167165
bsum += sir[2] * rbs;
168-
if (i > 0) {
169-
rinsum += sir[0]; ginsum += sir[1]; binsum += sir[2];
170-
} else {
171-
routsum += sir[0]; goutsum += sir[1]; boutsum += sir[2];
172-
}
166+
if (i > 0) rinsum += sir[0]; else routsum += sir[0];
167+
if (i > 0) ginsum += sir[1]; else goutsum += sir[1];
168+
if (i > 0) binsum += sir[2]; else boutsum += sir[2];
173169
}
174170
stackpointer = radius;
175171
for (x = 0; x < w; x++) {
@@ -197,14 +193,12 @@ private static Bitmap fastBlur(Bitmap sentBitmap, int radius) {
197193
for (i = -radius; i <= radius; i++) {
198194
yi = Math.max(0, yp) + x;
199195
sir = stack[i + radius];
200-
sir[0] = r[yi]; sir[1] = g[yi]; sir[2] = b[yi];
196+
sir[0] = r[yi]; sir[1] = g[yi]; sir[2] = b[2];
201197
rbs = r1 - Math.abs(i);
202198
rsum += r[yi] * rbs; gsum += g[yi] * rbs; bsum += b[yi] * rbs;
203-
if (i > 0) {
204-
rinsum += sir[0]; ginsum += sir[1]; binsum += sir[2];
205-
} else {
206-
routsum += sir[0]; goutsum += sir[1]; boutsum += sir[2];
207-
}
199+
if (i > 0) rinsum += sir[0]; else routsum += sir[0];
200+
if (i > 0) ginsum += sir[1]; else goutsum += sir[1];
201+
if (i > 0) binsum += sir[2]; else boutsum += sir[2];
208202
if (i < hm) yp += w;
209203
}
210204
yi = x;
@@ -228,7 +222,7 @@ private static Bitmap fastBlur(Bitmap sentBitmap, int radius) {
228222
}
229223
}
230224
bitmap.setPixels(pix, 0, w, 0, 0, w, h);
231-
sentBitmap.recycle(); // Giải phóng bitmap cũ sau khi copy
225+
sentBitmap.recycle();
232226
return bitmap;
233227
}
234228
}

0 commit comments

Comments
 (0)