gpt4 book ai didi

Android Blur View(模糊 View 后面的背景)

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:39:27 26 4
gpt4 key购买 nike

我正在尝试使图像的底部像图像中一样模糊,以便顶部的 View 。

我尝试使用 Rendenscript 对其进行模糊处理,但我无法仅对 View 后面的部分进行模糊处理。 :(

我见过很多图书馆,但几乎所有图书馆都模糊了整个图像,但不是图像的一部分。

此外,一个重要的部分是我在 ViewPager 中使用它,因此需要像 this in IOS 这样的快速和动态的东西。当它背后的图像发生变化时,它会重新绘制自己。

感谢任何帮助。感谢您的光临!

我的 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>

我的代码:

模糊生成器.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();


}

}

在我的 MainActivity 的 onCreate 中,我这样做:

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

结果如下:

enter image description here

最佳答案

将这两个类添加到您的应用中,

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

}

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

不要忘记将其添加到值> 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
-->

关于Android Blur View(模糊 View 后面的背景),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31808955/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com