Created
August 9, 2016 14:44
-
-
Save dka09/a71cd0ba8dbe1296052c98e47f19e88e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private ImageView backgroundImage; | |
private LinearLayout textContainer; | |
private void applyBlur() { | |
backgroundImage.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { | |
@Override | |
public boolean onPreDraw() { | |
backgroundImage.getViewTreeObserver().removeOnPreDrawListener(this); | |
backgroundImage.buildDrawingCache(); | |
Bitmap bmp = backgroundImage.getDrawingCache(); | |
Utility.blur(bmp, textContainer, getResources()); | |
return true; | |
} | |
}); | |
} | |
@Override | |
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { | |
super.onViewCreated(view, savedInstanceState); | |
backgroundImage = (ImageView) view.findViewById(R.id.background_image); | |
textContainer = (LinearLayout) view.findViewById(R.id.text_container); | |
... | |
applyBlur(); | |
} | |
// Utility.java | |
public static void blur(Bitmap bkg, View view, Resources resources) { | |
float scaleFactor = 8; | |
float radius = 5; | |
Bitmap overlay = Bitmap.createBitmap((int) (view.getMeasuredWidth() / scaleFactor), | |
(int) (view.getMeasuredHeight() / scaleFactor), Bitmap.Config.ARGB_8888); | |
Canvas canvas = new Canvas(overlay); | |
canvas.translate(-view.getLeft() / scaleFactor, -view.getTop() / scaleFactor); | |
canvas.scale(1 / scaleFactor, 1 / scaleFactor); | |
Paint paint = new Paint(); | |
paint.setFlags(Paint.FILTER_BITMAP_FLAG); | |
canvas.drawBitmap(bkg, 0, 0, paint); | |
overlay = FastBlur.doBlur(overlay, (int) radius, true); // FastBlur.java included | |
view.setBackground(new BitmapDrawable(resources, overlay)); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.bskyb.fbscore.util; | |
import android.graphics.Bitmap; | |
public class FastBlur { | |
public static Bitmap doBlur(Bitmap sentBitmap, int radius, boolean canReuseInBitmap) { | |
// Stack Blur v1.0 from | |
// http://www.quasimondo.com/StackBlurForCanvas/StackBlurDemo.html | |
// | |
// Java Author: Mario Klingemann <mario at quasimondo.com> | |
// http://incubator.quasimondo.com | |
// created Feburary 29, 2004 | |
// Android port : Yahel Bouaziz <yahel at kayenko.com> | |
// http://www.kayenko.com | |
// ported april 5th, 2012 | |
// This is a compromise between Gaussian Blur and Box blur | |
// It creates much better looking blurs than Box Blur, but is | |
// 7x faster than my Gaussian Blur implementation. | |
// | |
// I called it Stack Blur because this describes best how this | |
// filter works internally: it creates a kind of moving stack | |
// of colors whilst scanning through the image. Thereby it | |
// just has to add one new block of color to the right side | |
// of the stack and remove the leftmost color. The remaining | |
// colors on the topmost layer of the stack are either added on | |
// or reduced by one, depending on if they are on the right or | |
// on the left side of the stack. | |
// | |
// If you are using this algorithm in your code please add | |
// the following line: | |
// | |
// Stack Blur Algorithm by Mario Klingemann <[email protected]> | |
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); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* | |
* @param view - The view returned by onCreateView that is also passed into onViewCreated | |
*/ | |
private void animateGlint(final View view) { | |
final ViewTreeObserver observer = view.getViewTreeObserver(); | |
observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { | |
@Override | |
public void onGlobalLayout() { | |
observer.removeOnGlobalLayoutListener(this); | |
final Handler handler = new Handler(); | |
handler.postDelayed(new Runnable() { | |
@Override | |
public void run() { | |
ImageView glint = (ImageView) view.findViewById(R.id.glint); | |
int glintWidth = glint.getWidth(); | |
float moveInX = -(screenWidth + glintWidth + glintWidth); | |
TranslateAnimation animation = new TranslateAnimation(0.0f, moveInX, 0.0f, 0.0f); | |
animation.setDuration(1500); | |
glint.startAnimation(animation); | |
} | |
}, 1500); | |
} | |
}); | |
} | |
@Override | |
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { | |
super.onViewCreated(view, savedInstanceState); | |
... | |
animateGlint(view); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment