2015-08-04 4 views
8

J'essaie de rendre la partie inférieure d'une image floue pour la vue sur le dessus comme dans l'image.Android Flou Vue (arrière-plan flou derrière la vue)

J'ai essayé de le rendre flou à l'aide de Rendenscript mais je ne parviens pas à rendre flou uniquement la partie située derrière la vue. :(

J'ai vu beaucoup de bibliothèques, mais presque tous brouiller l'image entière, mais pas une partie de celui-ci.

En outre, une partie importante est que je me sers de ce dans un ViewPager et doit donc à . quelque chose rapide et dynamique comme this in IOS qui se redessine l'image moment derrière elle change

Toute aide est appréciée Merci pour s'arrêter par

Mon xml:.!

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:gravity="center" 
    android:orientation="vertical" > 

    <ImageView 
     android:id="@+id/image" 
     android:src="@drawable/broadstairs" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:scaleType="centerCrop" 
     android:layout_centerInParent="true"/> 

    <TextView 
     android:id="@+id/text" 
     android:layout_width="match_parent" 
     android:layout_height="200dp" 
     android:text="Hello World" 
     android:gravity="center" 
     android:layout_alignParentBottom="true" 
     android:textColor="@android:color/white" 
     android:textStyle="bold" 
     android:textSize="36sp"/> 
</RelativeLayout> 

Mon code:

BlurBuilder.java

public class BlurBuilder { 
    private static final float BITMAP_SCALE = 0.1f; 
    private static final float BLUR_RADIUS = 7.5f; 

    public static Bitmap blur(Context context, Bitmap image) { 
     int width = Math.round(image.getWidth() * BITMAP_SCALE); 
     int height = Math.round(image.getHeight() * BITMAP_SCALE); 

     Bitmap inputBitmap = Bitmap.createScaledBitmap(image, width, height, false); 
     Bitmap outputBitmap = Bitmap.createBitmap(inputBitmap); 

     RenderScript rs = RenderScript.create(context); 
     ScriptIntrinsicBlur theIntrinsic = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs)); 
     Allocation tmpIn = Allocation.createFromBitmap(rs, inputBitmap); 
     Allocation tmpOut = Allocation.createFromBitmap(rs, outputBitmap); 
     theIntrinsic.setRadius(BLUR_RADIUS); 
     theIntrinsic.setInput(tmpIn); 
     theIntrinsic.forEach(tmpOut); 
     tmpOut.copyTo(outputBitmap); 

     return outputBitmap; 
    } 

    @SuppressLint("NewApi") 
    public static void blur(final Context context, final Bitmap bitmap, final View view) { 

     new AsyncTask<Void, Void, Bitmap>() { 

      @Override 
      protected Bitmap doInBackground(Void... params) { 
       Paint paint = new Paint(); 
       paint.setFilterBitmap(true); 
       Bitmap cropImage = Bitmap.createBitmap(bitmap, 0, bitmap.getHeight() - view.getHeight(), bitmap.getWidth(), view.getHeight()); 

       return BlurBuilder.blur(context, cropImage); 
      } 


      @Override 
      protected void onPostExecute(Bitmap bitmap) { 
       super.onPostExecute(bitmap); 
       if (bitmap != null) { 
        int sdk = android.os.Build.VERSION.SDK_INT; 
        if (sdk < android.os.Build.VERSION_CODES.JELLY_BEAN) { 
         view.setBackgroundDrawable(new BitmapDrawable(context.getResources(), bitmap)); 
        } else { 
         view.setBackground(new BitmapDrawable(context.getResources(), bitmap)); 
        } 

       } 

      } 
     }.execute(); 


    } 

} 

Dans mon onCreate de MainActivity que je fais:

BlurBuilder.blur(BitmapActivity.this, ((BitmapDrawable) mView.getDrawable()).getBitmap(), mDummyView); 

est le résultat ci-dessous:

enter image description here

+2

Vous pouvez utiliser [FastBlur] (http://trickyandroid.com/ advanced-blurring-techniques /) –

+1

Peut-être qu'un flou transparent sur votre vue de dessous fera l'affaire. – NullByte

+0

@NullByte aime? –

Répondre

-1

Essayez applyBlur méthode:

private void applyBlur(ImageView image) { 
    image.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { 
     @Override 
     public boolean onPreDraw() { 
      image.getViewTreeObserver().removeOnPreDrawListener(this); 
      image.buildDrawingCache(); 

      Bitmap bmp = image.getDrawingCache(); 
      blur(bmp, text); 
      return true; 
     } 
    }); 
} 

@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) 
private void blur(Bitmap bkg, View view) { 
    long startMs = System.currentTimeMillis(); 

    float radius = 20; 

    Bitmap overlay = Bitmap.createBitmap((int) (view.getMeasuredWidth()), 
      (int) (view.getMeasuredHeight()), Bitmap.Config.ARGB_8888); 

    Canvas canvas = new Canvas(overlay); 

    canvas.translate(-view.getLeft(), -view.getTop()); 
    canvas.drawBitmap(bkg, 0, 0, null); 

    RenderScript rs = RenderScript.create(getActivity()); 

    Allocation overlayAlloc = Allocation.createFromBitmap(
      rs, overlay); 

    ScriptIntrinsicBlur blur = ScriptIntrinsicBlur.create(
      rs, overlayAlloc.getElement()); 

    blur.setInput(overlayAlloc); 

    blur.setRadius(radius); 

    blur.forEach(overlayAlloc); 

    overlayAlloc.copyTo(overlay); 

    view.setBackground(new BitmapDrawable(
      getResources(), overlay)); 

    rs.destroy(); 
} 
1

Ceci peut être réalisé par étapes suivantes:

  • Extrait l'image de fond de LinearLayout en recadrant l'image d'arrière-plan. Étendez maintenant la classe LinearLayout.

  • Remplacer la méthode OnDraw (Canvas mCanvas).

  • Créer deux méthodes dans votre classe personnalisée LinearLayout:

    1. DrawBitmap
    2. DrawColor.
  • Appelez d'abord la fonction DrawBitmap en donnant le décalage que vous avez obtenu de ViewPager à l'image d'arrière-plan afin que l'image se déplace lorsque l'utilisation balaye l'écran.

  • Enfin dessiner la couleur avec votre niveau de transparence

J'espère que cela résoudra votre problème.

Exemple de code pour cette

How to Blur a View

2

Ajouter ces deux classes à votre application,

1> BlurKit.Java

public class BlurKit { 

    private static BlurKit instance; 

    private RenderScript rs; 

    public static void init(Context context) { 
     if (instance != null) { 
      return; 
     } 

     instance = new BlurKit(); 
     instance.rs = RenderScript.create(context); 
    } 

    public Bitmap blur(Bitmap src, int radius) { 
     final Allocation input = Allocation.createFromBitmap(rs, src); 
     final Allocation output = Allocation.createTyped(rs, input.getType()); 
     final ScriptIntrinsicBlur script; 
     if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) { 
      script = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs)); 
      script.setRadius(radius); 
      script.setInput(input); 
      script.forEach(output); 
     } 
     output.copyTo(src); 
     return src; 
    } 

    public Bitmap blur(View src, int radius) { 
     Bitmap bitmap = getBitmapForView(src, 1f); 
     return blur(bitmap, radius); 
    } 

    public Bitmap fastBlur(View src, int radius, float downscaleFactor) { 
     Bitmap bitmap = getBitmapForView(src, downscaleFactor); 
     return blur(bitmap, radius); 
    } 

    private Bitmap getBitmapForView(View src, float downscaleFactor) { 
     Bitmap bitmap = Bitmap.createBitmap(
       (int) (src.getWidth() * downscaleFactor), 
       (int) (src.getHeight() * downscaleFactor), 
       Bitmap.Config.ARGB_4444 
     ); 

     Canvas canvas = new Canvas(bitmap); 
     Matrix matrix = new Matrix(); 
     matrix.preScale(downscaleFactor, downscaleFactor); 
     canvas.setMatrix(matrix); 
     src.draw(canvas); 

     return bitmap; 
    } 

    public static BlurKit getInstance() { 
     if (instance == null) { 
      throw new RuntimeException("BlurKit not initialized!"); 
     } 

     return instance; 
    } 

} 

2> BlurLayout.Java

public class BlurLayout extends FrameLayout { 

    public static final float DEFAULT_DOWNSCALE_FACTOR = 0.12f; 
    public static final int DEFAULT_BLUR_RADIUS = 12; 
    public static final int DEFAULT_FPS = 60; 

    // Customizable attributes 

    /** Factor to scale the view bitmap with before blurring. */ 
    private float mDownscaleFactor; 

    /** Blur radius passed directly to stackblur library. */ 
    private int mBlurRadius; 

    /** Number of blur invalidations to do per second. */ 
    private int mFPS; 

    // Calculated class dependencies 

    /** Reference to View for top-parent. For retrieval see {@link #getActivityView() getActivityView}. */ 
    private WeakReference<View> mActivityView; 

    public BlurLayout(Context context) { 
     super(context, null); 
    } 

    public BlurLayout(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     BlurKit.init(context); 

     TypedArray a = context.getTheme().obtainStyledAttributes(
       attrs, 
       R.styleable.BlurLayout, 
       0, 0); 

     try { 
      mDownscaleFactor = a.getFloat(R.styleable.BlurLayout_downscaleFactor, DEFAULT_DOWNSCALE_FACTOR); 
      mBlurRadius = a.getInteger(R.styleable.BlurLayout_blurRadius, DEFAULT_BLUR_RADIUS); 
      mFPS = a.getInteger(R.styleable.BlurLayout_fps, DEFAULT_FPS); 
     } finally { 
      a.recycle(); 
     } 

     if (mFPS > 0) { 
      Choreographer.getInstance().postFrameCallback(invalidationLoop); 
     } 
    } 

    /** Choreographer callback that re-draws the blur and schedules another callback. */ 
    private Choreographer.FrameCallback invalidationLoop = new Choreographer.FrameCallback() { 
     @Override 
     public void doFrame(long frameTimeNanos) { 
      invalidate(); 
      Choreographer.getInstance().postFrameCallbackDelayed(this, 1000/mFPS); 
     } 
    }; 

    /** 
    * {@inheritDoc} 
    */ 
    @Override 
    public void invalidate() { 
     super.invalidate(); 
     Bitmap bitmap = blur(); 
     if (bitmap != null) { 
      setBackground(new BitmapDrawable(bitmap)); 
     } 
    } 

    /** 
    * Recreates blur for content and sets it as the background. 
    */ 
    private Bitmap blur() { 
     if (getContext() == null) { 
      return null; 
     } 

     // Check the reference to the parent view. 
     // If not available, attempt to make it. 
     if (mActivityView == null || mActivityView.get() == null) { 
      mActivityView = new WeakReference<>(getActivityView()); 
      if (mActivityView.get() == null) { 
       return null; 
      } 
     } 

     // Calculate the relative point to the parent view. 
     Point pointRelativeToActivityView = getPositionInScreen(); 

     // Set alpha to 0 before creating the parent view bitmap. 
     // The blur view shouldn't be visible in the created bitmap. 
     setAlpha(0); 

     // Screen sizes for bound checks 
     int screenWidth = mActivityView.get().getWidth(); 
     int screenHeight = mActivityView.get().getHeight(); 

     // The final dimensions of the blurred bitmap. 
     int width = (int) (getWidth() * mDownscaleFactor); 
     int height = (int) (getHeight() * mDownscaleFactor); 

     // The X/Y position of where to crop the bitmap. 
     int x = (int) (pointRelativeToActivityView.x * mDownscaleFactor); 
     int y = (int) (pointRelativeToActivityView.y * mDownscaleFactor); 

     // Padding to add to crop pre-blur. 
     // Blurring straight to edges has side-effects so padding is added. 
     int xPadding = getWidth()/8; 
     int yPadding = getHeight()/8; 

     // Calculate padding independently for each side, checking edges. 
     int leftOffset = -xPadding; 
     leftOffset = x + leftOffset >= 0 ? leftOffset : 0; 

     int rightOffset = xPadding; 
     rightOffset = x + getWidth() + rightOffset <= screenWidth ? rightOffset : screenWidth - getWidth() - x; 

     int topOffset = -yPadding; 
     topOffset = y + topOffset >= 0 ? topOffset : 0; 

     int bottomOffset = yPadding; 
     bottomOffset = y + height + bottomOffset <= screenHeight ? bottomOffset : 0; 

     // Create parent view bitmap, cropped to the BlurLayout area with above padding. 
     Bitmap bitmap; 
     try { 
      bitmap = getDownscaledBitmapForView(
        mActivityView.get(), 
        new Rect(
          pointRelativeToActivityView.x + leftOffset, 
          pointRelativeToActivityView.y + topOffset, 
          pointRelativeToActivityView.x + getWidth() + Math.abs(leftOffset) + rightOffset, 
          pointRelativeToActivityView.y + getHeight() + Math.abs(topOffset) + bottomOffset 
        ), 
        mDownscaleFactor 
      ); 
     } catch (NullPointerException e) { 
      return null; 
     } 

     // Blur the bitmap. 
     bitmap = BlurKit.getInstance().blur(bitmap, mBlurRadius); 

     //Crop the bitmap again to remove the padding. 
     bitmap = Bitmap.createBitmap(
       bitmap, 
       (int) (Math.abs(leftOffset) * mDownscaleFactor), 
       (int) (Math.abs(topOffset) * mDownscaleFactor), 
       width, 
       height 
     ); 

     // Make self visible again. 
     setAlpha(1); 

     // Set background as blurred bitmap. 
     return bitmap; 
    } 

    /** 
    * Casts context to Activity and attempts to create a view reference using the window decor view. 
    * @return View reference for whole activity. 
    */ 
    private View getActivityView() { 
     Activity activity; 
     try { 
      activity = (Activity) getContext(); 
     } catch (ClassCastException e) { 
      return null; 
     } 

     return activity.getWindow().getDecorView().findViewById(android.R.id.content); 
    } 

    /** 
    * Returns the position in screen. Left abstract to allow for specific implementations such as 
    * caching behavior. 
    */ 
    private Point getPositionInScreen() { 
     return getPositionInScreen(this); 
    } 

    /** 
    * Finds the Point of the parent view, and offsets result by self getX() and getY(). 
    * @return Point determining position of the passed in view inside all of its ViewParents. 
    */ 
    private Point getPositionInScreen(View view) { 
     if (getParent() == null) { 
      return new Point(); 
     } 


     ViewGroup parent; 
     try { 
      parent = (ViewGroup) view.getParent(); 
     } catch (Exception e) { 
      return new Point(); 
     } 

     if (parent == null) { 
      return new Point(); 
     } 

     Point point = getPositionInScreen(parent); 
     point.offset((int) view.getX(), (int) view.getY()); 
     return point; 
    } 

    /** 
    * Users a View reference to create a bitmap, and downscales it using the passed in factor. 
    * Uses a Rect to crop the view into the bitmap. 
    * @return Bitmap made from view, downscaled by downscaleFactor. 
    * @throws NullPointerException 
    */ 
    private Bitmap getDownscaledBitmapForView(View view, Rect crop, float downscaleFactor) throws NullPointerException { 
     View screenView = view.getRootView(); 

     int width = (int) (crop.width() * downscaleFactor); 
     int height = (int) (crop.height() * downscaleFactor); 

     if (screenView.getWidth() <= 0 || screenView.getHeight() <= 0 || width <= 0 || height <= 0) { 
      throw new NullPointerException(); 
     } 

     float dx = -crop.left * downscaleFactor; 
     float dy = -crop.top * downscaleFactor; 

     Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_4444); 
     Canvas canvas = new Canvas(bitmap); 
     Matrix matrix = new Matrix(); 
     matrix.preScale(downscaleFactor, downscaleFactor); 
     matrix.postTranslate(dx, dy); 
     canvas.setMatrix(matrix); 
     screenView.draw(canvas); 

     return bitmap; 
    } 

    /** 
    * Sets downscale factor to use pre-blur. 
    * See {@link #mDownscaleFactor}. 
    */ 
    public void setDownscaleFactor(float downscaleFactor) { 
     this.mDownscaleFactor = downscaleFactor; 
     invalidate(); 
    } 

    /** 
    * Sets blur radius to use on downscaled bitmap. 
    * See {@link #mBlurRadius}. 
    */ 
    public void setBlurRadius(int blurRadius) { 
     this.mBlurRadius = blurRadius; 
     invalidate(); 
    } 

    /** 
    * Sets FPS to invalidate blur with. 
    * See {@link #mFPS}. 
    */ 
    public void setFPS(int fps) { 
     this.mFPS = fps; 
    } 

} 

dans le fichier XML:

   <FrameLayout 
         android:id="@+id/fl_uploadedView" 
         android:layout_width="match_parent" 
         android:layout_height="wrap_content" 
         android:layout_margin="@dimen/_10sdp"> 

         <ImageView 
          android:id="@+id/dv_uploadedPic" 
          android:layout_width="match_parent" 
          android:layout_height="@dimen/_150sdp" 
          android:contentDescription="@string/app_name" 
          android:scaleType="centerCrop" 
          android:src="@color/gray" /> 

         <BlurLayout 
          android:id="@+id/ll_blurView" 
          android:layout_width="match_parent" 
          android:layout_height="wrap_content" 
          android:layout_gravity="bottom"> 

         <TextView 
          android:id="@+id/tv_fileName" 
          android:layout_width="match_parent" 
          android:layout_height="wrap_content" 
          android:layout_gravity="left" 
          android:padding="@dimen/_5sdp" 
          android:textSize="@dimen/_10sdp" 
          /> 
       </BlurLayout> 
      </FrameLayout> 

Ne pas oublier d'ajouter à valeurs> attr.xml

<!-- 
     Blur Layout start 
     --> 
    <declare-styleable name="BlurLayout"> 
     <attr name="downscaleFactor" format="float" /> 
     <attr name="blurRadius" format="integer" /> 
     <attr name="fps" format="integer" /> 
    </declare-styleable> 

    <!-- 
     Blur Layout end 
    -->