Android ImageView blur animation(Android ImageView 模糊动画)
问题描述
我希望将模糊动画添加到 ImageView
,但要设置持续时间.因此,例如,我希望图像随着时间的推移而变得模糊.
I'm looking to add a blur animation to an ImageView
, but with a set duration. So, for example I want an image to blur out over time.
我已经有了模糊图像的方法,但我需要让它在 2 秒内从模糊变为无模糊.
I already have the method to blur the image, but what I need is to make it go from blur to none blur over, say, 2 seconds.
谁能帮帮我?
这是我目前必须模糊图像的方法.
This is the method I currently have to blur the image.
public Bitmap blur(Bitmap sentBitmap, int radius) {
// Stack Blur Algorithm by Mario Klingemann <mario@quasimondo.com>
Bitmap bitmap = sentBitmap.copy(sentBitmap.getConfig(), true);
if (radius < 1) {
return (null);
}
int w = bitmap.getWidth();
int h = bitmap.getHeight();
int[] pix = new int[w * h];
Log.e("pix", w + " " + h + " " + pix.length);
bitmap.getPixels(pix, 0, w, 0, 0, w, h);
int wm = w - 1;
int hm = h - 1;
int wh = w * h;
int div = radius + radius + 1;
int r[] = new int[wh];
int g[] = new int[wh];
int b[] = new int[wh];
int rsum, gsum, bsum, x, y, i, p, yp, yi, yw;
int vmin[] = new int[Math.max(w, h)];
int divsum = (div + 1) >> 1;
divsum *= divsum;
int dv[] = new int[256 * divsum];
for (i = 0; i < 256 * divsum; i++) {
dv[i] = (i / divsum);
}
yw = yi = 0;
int[][] stack = new int[div][3];
int stackpointer;
int stackstart;
int[] sir;
int rbs;
int r1 = radius + 1;
int routsum, goutsum, boutsum;
int rinsum, ginsum, binsum;
for (y = 0; y < h; y++) {
rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
for (i = -radius; i <= radius; i++) {
p = pix[yi + Math.min(wm, Math.max(i, 0))];
sir = stack[i + radius];
sir[0] = (p & 0xff0000) >> 16;
sir[1] = (p & 0x00ff00) >> 8;
sir[2] = (p & 0x0000ff);
rbs = r1 - Math.abs(i);
rsum += sir[0] * rbs;
gsum += sir[1] * rbs;
bsum += sir[2] * rbs;
if (i > 0) {
rinsum += sir[0];
ginsum += sir[1];
binsum += sir[2];
} else {
routsum += sir[0];
goutsum += sir[1];
boutsum += sir[2];
}
}
stackpointer = radius;
for (x = 0; x < w; x++) {
r[yi] = dv[rsum];
g[yi] = dv[gsum];
b[yi] = dv[bsum];
rsum -= routsum;
gsum -= goutsum;
bsum -= boutsum;
stackstart = stackpointer - radius + div;
sir = stack[stackstart % div];
routsum -= sir[0];
goutsum -= sir[1];
boutsum -= sir[2];
if (y == 0) {
vmin[x] = Math.min(x + radius + 1, wm);
}
p = pix[yw + vmin[x]];
sir[0] = (p & 0xff0000) >> 16;
sir[1] = (p & 0x00ff00) >> 8;
sir[2] = (p & 0x0000ff);
rinsum += sir[0];
ginsum += sir[1];
binsum += sir[2];
rsum += rinsum;
gsum += ginsum;
bsum += binsum;
stackpointer = (stackpointer + 1) % div;
sir = stack[(stackpointer) % div];
routsum += sir[0];
goutsum += sir[1];
boutsum += sir[2];
rinsum -= sir[0];
ginsum -= sir[1];
binsum -= sir[2];
yi++;
}
yw += w;
}
for (x = 0; x < w; x++) {
rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
yp = -radius * w;
for (i = -radius; i <= radius; i++) {
yi = Math.max(0, yp) + x;
sir = stack[i + radius];
sir[0] = r[yi];
sir[1] = g[yi];
sir[2] = b[yi];
rbs = r1 - Math.abs(i);
rsum += r[yi] * rbs;
gsum += g[yi] * rbs;
bsum += b[yi] * rbs;
if (i > 0) {
rinsum += sir[0];
ginsum += sir[1];
binsum += sir[2];
} else {
routsum += sir[0];
goutsum += sir[1];
boutsum += sir[2];
}
if (i < hm) {
yp += w;
}
}
yi = x;
stackpointer = radius;
for (y = 0; y < h; y++) {
// Preserve alpha channel: ( 0xff000000 & pix[yi] )
pix[yi] = ( 0xff000000 & pix[yi] ) | ( dv[rsum] << 16 ) | ( dv[gsum] << 8 ) | dv[bsum];
rsum -= routsum;
gsum -= goutsum;
bsum -= boutsum;
stackstart = stackpointer - radius + div;
sir = stack[stackstart % div];
routsum -= sir[0];
goutsum -= sir[1];
boutsum -= sir[2];
if (x == 0) {
vmin[y] = Math.min(y + r1, hm) * w;
}
p = x + vmin[y];
sir[0] = r[p];
sir[1] = g[p];
sir[2] = b[p];
rinsum += sir[0];
ginsum += sir[1];
binsum += sir[2];
rsum += rinsum;
gsum += ginsum;
bsum += binsum;
stackpointer = (stackpointer + 1) % div;
sir = stack[stackpointer];
routsum += sir[0];
goutsum += sir[1];
boutsum += sir[2];
rinsum -= sir[0];
ginsum -= sir[1];
binsum -= sir[2];
yi += w;
}
}
Log.e("pix", w + " " + h + " " + pix.length);
bitmap.setPixels(pix, 0, w, 0, 0, w, h);
return (bitmap);
}
推荐答案
模糊效果在 Android 上总是很困难.本质上,您必须在外观和性能之间做出决定.模糊看起来越好,花费的时间就越长,如果模糊本身不是瞬时的,那么你就无法真正为模糊设置动画.
Blur effects are always difficult on Android. Essentially you have to decide between looks and performance. The better the blur looks the longer it takes, and if the blurring itself is not instantaneous then you cannot really animate the blur.
你原来的模糊算法产生了非常好的结果,但正因为如此它也很慢,使得模糊动画变得不可能.为了演示如何有效地模糊此图像,我通过缩小位图创建了一个简单的模糊动画:
You original blurring algorithm produces really good results, but because of that it is also very slow making a blur animation impossible. Just to demonstrate what it would take to effectively blur this image I have created a simple blur animation by scaling the bitmap down:
public class BlurAnimation extends Animation {
private final ImageView imageView;
private final Bitmap bitmap;
private final float startValue;
private final float stopValue;
private final float difValue;
private BlurAnimation(ImageView imageView, Bitmap bitmap, int startValue, int stopValue) {
this.imageView = imageView;
this.bitmap = bitmap;
this.startValue = startValue;
this.stopValue = stopValue;
this.difValue = stopValue - startValue;
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
super.applyTransformation(interpolatedTime, t);
int current = (int)(this.difValue * interpolatedTime + this.startValue + 0.5f);
Bitmap blurred = quickBlur(this.bitmap, current);
this.imageView.setImageBitmap(blurred);
}
public Bitmap quickBlur(Bitmap bitmap, int factor) {
if(factor <= 0) {
return Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
}
return Bitmap.createScaledBitmap(bitmap, bitmap.getWidth() / factor, bitmap.getHeight() / factor, true);
}
}
这工作得很好(尽管仍有一些滞后),但结果无法与您的模糊算法进行比较,它看起来很糟糕:
This works quite well (even though there is still some lag), but the results cannot be compared with your blur algorithm, it just looks terrible:
所以你看,在模糊图像时很难将性能和美观结合起来,但首先有一些选项RenderScript
.RenderScript
非常快,并且具有内置的高斯模糊滤镜.我从未使用过它,但据我所知,它可能是您问题的解决方案.
So you see, it is very difficult to combine performance and good looks when it comes to blurring an image, but there are some options first and foremost RenderScript
. RenderScript
is very fast and has a built in gaussian blur filter. I have never used it, but from what I hear it might be the solution to your problem.
您也可以尝试加载已缩小版本的图像,这将产生与上述 gif 相同的效果,但速度会更快.缺点是在 Animation
中使用它还是有问题的,但如果你只需要一张模糊的图像并且你并不真正关心质量,那么你应该选择这个选项.
You can also try to load already scaled down versions of an image, this would produce the same effect as in the gif above, but would be even faster. The drawback is that using this in an Animation
is again problematic, but if you just need a blurred image and you don't really care about quality then you should go for this option.
您可以在此答案中找到有关 RenderScript
和其他快速模糊选项的更多信息强>
You can find more information about RenderScript
and other fast blur options in this answer
这篇关于Android ImageView 模糊动画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:Android ImageView 模糊动画
基础教程推荐
- 当从同一个组件调用时,两个 IBAction 触发的顺序是什么? 2022-01-01
- UIWebView 委托方法 shouldStartLoadWithRequest:在 WKWebView 中等效? 2022-01-01
- Android:对话框关闭而不调用关闭 2022-01-01
- android 应用程序已发布,但在 google play 中找不到 2022-01-01
- Kivy Buildozer 无法构建 apk,命令失败:./distribute.sh -m “kivy"d 2022-01-01
- 如何在 UIImageView 中异步加载图像? 2022-01-01
- 如何在没有IB的情况下将2个按钮添加到右侧的UINavigationbar? 2022-01-01
- 在 gmail 中为 ios 应用程序检索朋友的朋友 2022-01-01
- 如何让对象对 Cocos2D 中的触摸做出反应? 2022-01-01
- 如何在 iPhone 上显示来自 API 的 HTML 文本? 2022-01-01