2015-08-04 27 views
8

Tôi đang cố gắng tạo phần dưới cùng của Làm mờ hình ảnh cho chế độ xem ở trên cùng như trong hình ảnh.Chế độ xem Blur Android (Nền mờ phía sau chế độ xem)

Tôi đã thử làm mờ nó bằng cách sử dụng Rendenscript nhưng tôi không thể chỉ làm mờ phần phía sau chế độ xem. :(

Tôi đã thấy nhiều thư viện nhưng hầu như tất cả trong số họ làm mờ toàn bộ hình ảnh, nhưng không phải là một phần của nó.

Ngoài ra, một phần quan trọng là tôi đang sử dụng này bên trong một ViewPager và do đó cần phải . được nhanh chóng và năng động giống như this in IOS mà vẽ lại bản thân hình ảnh khoảnh khắc đằng sau nó thay đổi

Any help is appreciated Cảm ơn đã dừng lại do

xml của tôi:.!

<?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> 

Mã của tôi:

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(); 


    } 

} 

Trong onCreate MainActivity tôi tôi làm:

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

Dưới đây là kết quả:

enter image description here

+2

Bạn có thể sử dụng [FastBlur] (http://trickyandroid.com/ tiên tiến-blurring-kỹ thuật /) –

+1

Có lẽ mờ trong suốt trên xem dưới cùng của bạn sẽ làm các trick. – NullByte

+0

@NullByte thích? –

Trả lời

-1

Hãy thử applyBlur phương pháp:

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

này có thể đạt được trong các bước sau:

  • Trích xuất hình ảnh nền của LinearLayout bằng cách cắt ảnh nền. Bây giờ mở rộng Lớp LinearLayout.

  • Ghi đè phương thức OnDraw (Canvas mCanvas).

  • Tạo hai phương pháp trong LinearLayout Lớp Tuỳ chỉnh của bạn:

    1. DrawBitmap
    2. DrawColor.
  • Đầu tiên hãy gọi hàm DrawBitmap bằng cách cho bù đắp bạn nhận từ ViewPager sang hình nền để hình ảnh di chuyển khi sử dụng vuốt màn hình.

  • Cuối cùng vẽ màu với mức độ trong suốt của bạn

Tôi hy vọng điều này sẽ giải quyết vấn đề của bạn.

mẫu mã cho

How to Blur a View

2

này Thêm hai loại cổ phiếu này để ứng dụng của bạn,

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; 
    } 

} 

trong tập tin 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> 

Đừng quên để thêm video này giá trị> 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 
    --> 
Các vấn đề liên quan