246 lines
7.2 KiB
Java
246 lines
7.2 KiB
Java
package com.xscm.moduleutil.utils;
|
|
|
|
import android.graphics.Bitmap;
|
|
import android.graphics.Color;
|
|
import android.graphics.PorterDuff;
|
|
import android.graphics.drawable.BitmapDrawable;
|
|
import android.graphics.drawable.Drawable;
|
|
|
|
import com.blankj.utilcode.util.ScreenUtils;
|
|
|
|
|
|
public class FastBlurUtil {
|
|
public static Bitmap doBlur(Bitmap sentBitmap, int radius, boolean canReuseInBitmap) {
|
|
Bitmap bitmap;
|
|
if (canReuseInBitmap) {
|
|
bitmap = sentBitmap;
|
|
} else {
|
|
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 div = radius + radius + 1;
|
|
|
|
int r[] = new int[wh];
|
|
int g[] = new int[wh];
|
|
int b[] = new int[wh];
|
|
int rsum, gsum, bsum, x, y, i, p, yp, yi, yw;
|
|
int vmin[] = new int[Math.max(w, h)];
|
|
|
|
int divsum = (div + 1) >> 1;
|
|
divsum *= divsum;
|
|
int dv[] = new int[256 * divsum];
|
|
for (i = 0; i < 256 * divsum; i++) {
|
|
dv[i] = (i / divsum);
|
|
}
|
|
|
|
yw = yi = 0;
|
|
|
|
int[][] stack = new int[div][3];
|
|
int stackpointer;
|
|
int stackstart;
|
|
int[] sir;
|
|
int rbs;
|
|
int r1 = radius + 1;
|
|
int routsum, goutsum, boutsum;
|
|
int rinsum, ginsum, binsum;
|
|
|
|
for (y = 0; y < h; y++) {
|
|
rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
|
|
for (i = -radius; i <= radius; i++) {
|
|
p = pix[yi + Math.min(wm, Math.max(i, 0))];
|
|
sir = stack[i + radius];
|
|
sir[0] = (p & 0xff0000) >> 16;
|
|
sir[1] = (p & 0x00ff00) >> 8;
|
|
sir[2] = (p & 0x0000ff);
|
|
rbs = r1 - Math.abs(i);
|
|
rsum += sir[0] * rbs;
|
|
gsum += sir[1] * rbs;
|
|
bsum += sir[2] * rbs;
|
|
if (i > 0) {
|
|
rinsum += sir[0];
|
|
ginsum += sir[1];
|
|
binsum += sir[2];
|
|
} else {
|
|
routsum += sir[0];
|
|
goutsum += sir[1];
|
|
boutsum += sir[2];
|
|
}
|
|
}
|
|
stackpointer = radius;
|
|
|
|
for (x = 0; x < w; x++) {
|
|
|
|
r[yi] = dv[rsum];
|
|
g[yi] = dv[gsum];
|
|
b[yi] = dv[bsum];
|
|
|
|
rsum -= routsum;
|
|
gsum -= goutsum;
|
|
bsum -= boutsum;
|
|
|
|
stackstart = stackpointer - radius + div;
|
|
sir = stack[stackstart % div];
|
|
|
|
routsum -= sir[0];
|
|
goutsum -= sir[1];
|
|
boutsum -= sir[2];
|
|
|
|
if (y == 0) {
|
|
vmin[x] = Math.min(x + radius + 1, wm);
|
|
}
|
|
p = pix[yw + vmin[x]];
|
|
|
|
sir[0] = (p & 0xff0000) >> 16;
|
|
sir[1] = (p & 0x00ff00) >> 8;
|
|
sir[2] = (p & 0x0000ff);
|
|
|
|
rinsum += sir[0];
|
|
ginsum += sir[1];
|
|
binsum += sir[2];
|
|
|
|
rsum += rinsum;
|
|
gsum += ginsum;
|
|
bsum += binsum;
|
|
|
|
stackpointer = (stackpointer + 1) % div;
|
|
sir = stack[(stackpointer) % div];
|
|
|
|
routsum += sir[0];
|
|
goutsum += sir[1];
|
|
boutsum += sir[2];
|
|
|
|
rinsum -= sir[0];
|
|
ginsum -= sir[1];
|
|
binsum -= sir[2];
|
|
|
|
yi++;
|
|
}
|
|
yw += w;
|
|
}
|
|
for (x = 0; x < w; x++) {
|
|
rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
|
|
yp = -radius * w;
|
|
for (i = -radius; i <= radius; i++) {
|
|
yi = Math.max(0, yp) + x;
|
|
|
|
sir = stack[i + radius];
|
|
|
|
sir[0] = r[yi];
|
|
sir[1] = g[yi];
|
|
sir[2] = b[yi];
|
|
|
|
rbs = r1 - Math.abs(i);
|
|
|
|
rsum += r[yi] * rbs;
|
|
gsum += g[yi] * rbs;
|
|
bsum += b[yi] * rbs;
|
|
|
|
if (i > 0) {
|
|
rinsum += sir[0];
|
|
ginsum += sir[1];
|
|
binsum += sir[2];
|
|
} else {
|
|
routsum += sir[0];
|
|
goutsum += sir[1];
|
|
boutsum += sir[2];
|
|
}
|
|
|
|
if (i < hm) {
|
|
yp += w;
|
|
}
|
|
}
|
|
yi = x;
|
|
stackpointer = radius;
|
|
for (y = 0; y < h; y++) {
|
|
// Preserve alpha channel: ( 0xff000000 & pix[yi] )
|
|
pix[yi] = (0xff000000 & pix[yi]) | (dv[rsum] << 16) | (dv[gsum] << 8) | dv[bsum];
|
|
|
|
rsum -= routsum;
|
|
gsum -= goutsum;
|
|
bsum -= boutsum;
|
|
|
|
stackstart = stackpointer - radius + div;
|
|
sir = stack[stackstart % div];
|
|
|
|
routsum -= sir[0];
|
|
goutsum -= sir[1];
|
|
boutsum -= sir[2];
|
|
|
|
if (x == 0) {
|
|
vmin[y] = Math.min(y + r1, hm) * w;
|
|
}
|
|
p = x + vmin[y];
|
|
|
|
sir[0] = r[p];
|
|
sir[1] = g[p];
|
|
sir[2] = b[p];
|
|
|
|
rinsum += sir[0];
|
|
ginsum += sir[1];
|
|
binsum += sir[2];
|
|
|
|
rsum += rinsum;
|
|
gsum += ginsum;
|
|
bsum += binsum;
|
|
|
|
stackpointer = (stackpointer + 1) % div;
|
|
sir = stack[stackpointer];
|
|
|
|
routsum += sir[0];
|
|
goutsum += sir[1];
|
|
boutsum += sir[2];
|
|
|
|
rinsum -= sir[0];
|
|
ginsum -= sir[1];
|
|
binsum -= sir[2];
|
|
|
|
yi += w;
|
|
}
|
|
}
|
|
|
|
bitmap.setPixels(pix, 0, w, 0, 0, w, h);
|
|
|
|
return (bitmap);
|
|
}
|
|
|
|
|
|
public static Drawable getForegroundDrawable(Bitmap musicPicRes) {
|
|
/*得到屏幕的宽高比,以便按比例切割图片一部分*/
|
|
final float widthHeightSize = (float) (ScreenUtils.getScreenWidth()
|
|
* 1.0 / ScreenUtils.getScreenHeight() * 1.0);
|
|
|
|
Bitmap bitmap = musicPicRes;
|
|
int cropBitmapWidth = (int) (widthHeightSize * bitmap.getHeight());
|
|
int cropBitmapWidthX = (int) ((bitmap.getWidth() - cropBitmapWidth) / 2.0);
|
|
|
|
/*切割部分图片*/
|
|
Bitmap cropBitmap = Bitmap.createBitmap(bitmap, cropBitmapWidthX, 0, cropBitmapWidth,
|
|
bitmap.getHeight());
|
|
/*缩小图片*/
|
|
Bitmap scaleBitmap = Bitmap.createScaledBitmap(cropBitmap, bitmap.getWidth() / 50, bitmap
|
|
.getHeight() / 50, false);
|
|
/*模糊化*/
|
|
final Bitmap blurBitmap = FastBlurUtil.doBlur(scaleBitmap, 8, true);
|
|
|
|
final Drawable foregroundDrawable = new BitmapDrawable(blurBitmap);
|
|
/*加入灰色遮罩层,避免图片过亮影响其他控件*/
|
|
foregroundDrawable.setColorFilter(Color.GRAY, PorterDuff.Mode.MULTIPLY);
|
|
return foregroundDrawable;
|
|
}
|
|
|
|
|
|
}
|