77import android .graphics .Bitmap ;
88import android .graphics .Canvas ;
99import android .graphics .Paint ;
10+ import android .graphics .Path ;
1011import android .graphics .Rect ;
1112import android .os .Build ;
1213import android .util .AttributeSet ;
2324 * <li>realtimeBlurRadius (10dp)</li>
2425 * <li>realtimeDownsampleFactor (4)</li>
2526 * <li>realtimeOverlayColor (#aaffffff)</li>
27+ * <li>realtimeIsCircle (false)</li>
2628 * </ul>
2729 */
2830public class RealtimeBlurView extends View {
2931
3032 private float mDownsampleFactor ; // default 4
3133 private int mOverlayColor ; // default #aaffffff
3234 private float mBlurRadius ; // default 10dp (0 < r <= 25)
35+ private boolean mIsCircle = false , // default false
36+ isCircleDrawn = false ;
37+
3338
3439 private final BlurImpl mBlurImpl ;
3540 private boolean mDirty ;
@@ -56,6 +61,7 @@ public RealtimeBlurView(Context context, AttributeSet attrs) {
5661 TypedValue .applyDimension (TypedValue .COMPLEX_UNIT_DIP , 10 , context .getResources ().getDisplayMetrics ()));
5762 mDownsampleFactor = a .getFloat (R .styleable .RealtimeBlurView_realtimeDownsampleFactor , 4 );
5863 mOverlayColor = a .getColor (R .styleable .RealtimeBlurView_realtimeOverlayColor , 0xAAFFFFFF );
64+ mIsCircle = a .getBoolean (R .styleable .RealtimeBlurView_realtimeIsCircle , false );
5965 a .recycle ();
6066
6167 mPaint = new Paint ();
@@ -270,7 +276,16 @@ public boolean onPreDraw() {
270276 mBlurringCanvas .restoreToCount (rc );
271277 }
272278
273- blur (mBitmapToBlur , mBlurredBitmap );
279+ if (mIsCircle ) {
280+ if (!isCircleDrawn ) {
281+ isCircleDrawn = true ;
282+ mBitmapToBlur = getBitmapClippedCircle (mBitmapToBlur );
283+
284+ blur (mBitmapToBlur , mBlurredBitmap );
285+ }
286+ } else {
287+ blur (mBitmapToBlur , mBlurredBitmap );
288+ }
274289
275290 if (redrawBitmap || mDifferentRoot ) {
276291 invalidate ();
@@ -351,11 +366,41 @@ protected void drawBlurredBitmap(Canvas canvas, Bitmap blurredBitmap, int overla
351366 canvas .drawBitmap (blurredBitmap , mRectSrc , mRectDst , null );
352367 }
353368 mPaint .setColor (overlayColor );
354- canvas .drawRect (mRectDst , mPaint );
355- }
356369
357- private static class StopException extends RuntimeException {
370+ if (mIsCircle ) {
371+ canvas .drawCircle (getWidth () / 2f , getHeight () / 2f , getWidth () / 2f , mPaint );
372+ } else {
373+ canvas .drawRect (mRectDst , mPaint );
374+ }
358375 }
359376
377+ /**
378+ * https://stackoverflow.com/a/15489830
379+ *
380+ * @param bitmap - the Bitmap that needs to be circle clipped
381+ * @return - returns the new clipped Bitmap
382+ */
383+ public static Bitmap getBitmapClippedCircle (Bitmap bitmap ) {
384+
385+ final int width = bitmap .getWidth ();
386+ final int height = bitmap .getHeight ();
387+ final Bitmap outputBitmap = Bitmap .createBitmap (width , height , Bitmap .Config .ARGB_8888 );
388+
389+ final Path path = new Path ();
390+ path .addCircle (
391+ (float )(width / 2 )
392+ , (float )(height / 2 )
393+ , (float ) Math .min (width , (height / 2 ))
394+ , Path .Direction .CCW );
395+
396+ final Canvas canvas = new Canvas (outputBitmap );
397+ canvas .clipPath (path );
398+ canvas .drawBitmap (bitmap , 0 , 0 , null );
399+ return outputBitmap ;
400+ }
401+
402+ private static class StopException extends RuntimeException { }
403+
360404 private static StopException STOP_EXCEPTION = new StopException ();
405+
361406}
0 commit comments