package com.smartisanos.sidebar.util;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BlurMaskFilter;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
public class HolographicOutlineHelper {
private static final String TAG = "HolographicOutlineHelper";
private final Paint mHolographicPaint = new Paint();
private final Paint mBlurPaint = new Paint();
private final Paint mErasePaint = new Paint();
private final Paint mAlphaClipPaint = new Paint();
public static final int MAX_OUTER_BLUR_RADIUS;
public static final int MIN_OUTER_BLUR_RADIUS;
private static final float SCALE = 1.5f;
static {
final float scale = 1.5f;
MIN_OUTER_BLUR_RADIUS = (int) (scale * 1.0f);
MAX_OUTER_BLUR_RADIUS = (int) (scale * 12.0f);
}
private int[] mTempOffset = new int[2];
HolographicOutlineHelper() {
mHolographicPaint.setFilterBitmap(true);
mHolographicPaint.setAntiAlias(true);
mBlurPaint.setFilterBitmap(true);
mBlurPaint.setAntiAlias(true);
mErasePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
mErasePaint.setFilterBitmap(true);
mErasePaint.setAntiAlias(true);
}
Bitmap applyCustomExpensiveOutlineWithBlur(Bitmap srcDst, Canvas srcDstCanvas, int color,
int outlineColor, float radius) {
// We start by removing most of the alpha channel so as to ignore shadows, and
// other types of partial transparency when defining the shape of the object
Bitmap glowShape = srcDst.extractAlpha(mAlphaClipPaint, mTempOffset);
BlurMaskFilter outerBlurMaskFilter = new BlurMaskFilter(SCALE * radius, BlurMaskFilter.Blur.NORMAL);
mBlurPaint.setMaskFilter(outerBlurMaskFilter);
int[] outerBlurOffset = new int[2];
Bitmap thickOuterBlur = glowShape.extractAlpha(mBlurPaint, outerBlurOffset);
int[] brightOutlineOffset = new int[2];
Bitmap brightOutline = glowShape.extractAlpha(mBlurPaint, brightOutlineOffset);
// calculate the inner blur
srcDstCanvas.setBitmap(glowShape);
srcDstCanvas.drawColor(0xFF000000, PorterDuff.Mode.CLEAR);
BlurMaskFilter innerBlurMaskFilter = new BlurMaskFilter(SCALE * radius, BlurMaskFilter.Blur.OUTER);
mBlurPaint.setMaskFilter(innerBlurMaskFilter);
int[] thickInnerBlurOffset = new int[2];
Bitmap thickInnerBlur = glowShape.extractAlpha(mBlurPaint, thickInnerBlurOffset);
// mask out the inner blur
srcDstCanvas.setBitmap(thickInnerBlur);
srcDstCanvas.drawBitmap(glowShape, -thickInnerBlurOffset[0],
-thickInnerBlurOffset[1], mErasePaint);
srcDstCanvas.drawRect(0, 0, -thickInnerBlurOffset[0], thickInnerBlur.getHeight(),
mErasePaint);
srcDstCanvas.drawRect(0, 0, thickInnerBlur.getWidth(), -thickInnerBlurOffset[1],
mErasePaint);
Bitmap dest = Bitmap.createBitmap(brightOutline.getWidth(), brightOutline.getHeight(), Bitmap.Config.ARGB_8888);
float offsetx = (brightOutline.getWidth() - srcDst.getWidth()) / 2f;
// draw the inner and outer blur
srcDstCanvas.setBitmap(dest);
// srcDstCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
mHolographicPaint.setColor(color);
srcDstCanvas.drawBitmap(thickInnerBlur, thickInnerBlurOffset[0] + offsetx, thickInnerBlurOffset[1],
mHolographicPaint);
srcDstCanvas.drawBitmap(thickOuterBlur, outerBlurOffset[0] + offsetx, outerBlurOffset[1],
mHolographicPaint);
// draw the bright outline
mHolographicPaint.setColor(outlineColor);
srcDstCanvas.drawBitmap(brightOutline, brightOutlineOffset[0] + offsetx, brightOutlineOffset[1],
mHolographicPaint);
// cleanup
srcDstCanvas.setBitmap(null);
brightOutline.recycle();
thickOuterBlur.recycle();
thickInnerBlur.recycle();
glowShape.recycle();
return dest;
}
public static int[][] ICON_SHADOW_COLOR = new int[2][];
static {
ICON_SHADOW_COLOR[0] = new int[] {0x2f000000, 0x3f000000};
ICON_SHADOW_COLOR[1] = new int[] {0x12000000, 0x12000000};
}
public static Bitmap createDragOutline(Bitmap bm, int shadowIndex) {
int sh = 246;
float w = 192;
int[] radius = {9, 3};
int[] color = ICON_SHADOW_COLOR[shadowIndex];
final Bitmap b = Bitmap.createBitmap(sh,
sh, Bitmap.Config.ARGB_8888);
Paint p = new Paint();
p.setAntiAlias(true);
Canvas c = new Canvas(b);
final float deltax = (sh - w) / 2;
final float deltay = deltax / 2;
for(int i = 0; i < radius.length; i++) {
Bitmap bt = getOutlineFill(bm, new Canvas(),
radius[i], color[i]);
float deltaxs = (sh - bt.getWidth()) / 2;
float deltays = deltay + Math.round(Math.sqrt(radius[i]));
c.drawBitmap(bt, deltaxs, deltays, p);
bt.recycle();
}
Paint pa = new Paint();
c.drawBitmap(bm, deltax, deltay, pa);
return b;
}
public static Bitmap getOutlineFill(Bitmap bm, Canvas canvas, float r, int alpha) {
HolographicOutlineHelper mOutlineHelper = new HolographicOutlineHelper();
final int outlineColor = alpha;
final Bitmap b = Bitmap.createBitmap(
bm.getWidth() + 2 * Math.round(r), bm.getHeight() + 2 * Math.round(r), Bitmap.Config.ARGB_8888);
canvas.setBitmap(b);
canvas.drawBitmap(bm, Math.round(r), Math.round(r), new Paint());
Bitmap dest = mOutlineHelper.applyCustomExpensiveOutlineWithBlur(b, canvas, outlineColor, outlineColor, r);
canvas.setBitmap(null);
return dest;
}
public static Bitmap getOutline(Context context, Bitmap bm, int innerColor, int outerColor, int radius) {
Canvas canvas = new Canvas();
final Bitmap b = Bitmap.createBitmap(bm.getWidth(),
bm.getHeight(), Bitmap.Config.ARGB_8888);
canvas.setBitmap(b);
Paint paint = new Paint();
BlurMaskFilter blurFilter = new BlurMaskFilter(radius,
BlurMaskFilter.Blur.OUTER);
Paint shadowPaint = new Paint();
shadowPaint.setMaskFilter(blurFilter);
int[] outerPosition = new int[2];
Bitmap shadowBitmap = bm.extractAlpha(shadowPaint, outerPosition);
paint.setColor(outerColor);
canvas.drawBitmap(shadowBitmap, outerPosition[0], outerPosition[1], paint);
BlurMaskFilter blurFilter2 = new BlurMaskFilter(radius,
BlurMaskFilter.Blur.INNER);
Paint shadowPaint2 = new Paint();
shadowPaint.setMaskFilter(blurFilter2);
int[] innerPosition = new int[2];
Bitmap shadowBitmap2 = bm.extractAlpha(shadowPaint2, innerPosition);
paint.setColor(innerColor);
canvas.drawBitmap(shadowBitmap2, -innerPosition[0], -innerPosition[1], paint);
return b;
}
}