问题描述
我在找一个模糊的动画添加到的ImageView
,但在一段时间。因此,例如我想要的图像模糊随着时间的推移。
我已经有模糊图像的方法,但我需要的是让它从模糊到没有模糊过,比方说,2秒。
任何人可以帮助我吗?
编辑:这是方法我现在有模糊的图像
。 公共位图模糊(位图sentBitmap,INT半径){
//堆栈模糊算法由马里奥·克林格曼< [email protected]>
点阵位图= sentBitmap.copy(sentBitmap.getConfig(),TRUE);
如果(半径小于1){
返程(空);
}
INT W = bitmap.getWidth();
INT H = bitmap.getHeight();
INT [] PIX =新INT [W * H]。
Log.e(PIX,W ++ H ++ pix.length);
bitmap.getPixels(PIX,0,瓦特,0,0,W,H);
INT WM = W - 1;
INT HM = H - 1;
INT WH = W * H;
中期息=半径+半径+ 1;
INT R [] =新的INT [WH]
INT政[] =新的INT [WH]
INT B〔] =新的INT [WH]
INT率R sum,GSUM,bsum,X,Y,I,P,YP,苡仁,YW;
INT VMIN [] =新的INT [Math.max(W,H)];
INT divsum =(DIV + 1)GT;> 1;
divsum * = divsum;
INT DV [] =新的INT [256 * divsum]。
对于(i = 0; I< 256 * divsum;我++){
的dv [I] =(I / divsum);
}
YW =义= 0;
INT [] [] =栈新INT [股利] [3];
INT stackpointer;
INT stackstart;
INT []先生。
诠释RBS;
INT R1 =半径+ 1;
INT routsum,goutsum,boutsum;
INT rinsum,ginsum,binsum;
对于(Y = 0; Y< H; Y ++){
rinsum = ginsum = binsum = routsum = goutsum = boutsum =率R sum = GSUM = bsum = 0;
对于(i = -radius; I< =半径;我++){
P = PIX [易+ Math.min(WM,Math.max(I,0))];
爵士=栈[1 +半径]。
先生[0] =(P&安培;为0xFF0000)GT;> 16;
先生[1] =(P&安培; 0x00ff00)GT;> 8;
先生[2] =(P&安培; 0x0000ff);
RBS = R1 - Math.abs(ⅰ);
率R sum + =先生[0] * RBS;
GSUM + =先生[1] * RBS;
bsum + =先生[2] * RBS;
如果(ⅰ大于0){
rinsum + =先生[0];
ginsum + =先生[1];
binsum + =先生[2];
} 其他 {
routsum + =先生[0];
goutsum + =先生[1];
boutsum + =先生[2];
}
}
stackpointer =半径;
为(X = 0; X - 其中;瓦特; X ++){
- [R [易] = DV [率R sum]
政[易] = DV [GSUM]
B〔义] = DV [bsum]
率R sum - = routsum;
GSUM - = goutsum;
bsum - = boutsum;
stackstart = stackpointer - 半径+ DIV;
爵士=栈[stackstart%DIV]。
routsum - =先生[0];
goutsum - =先生[1];
boutsum - =先生[2];
如果(Y == 0){
VMIN [X] = Math.min(X +半径+ 1,WM);
}
p值= PIX [YW + VMIN [X]];
先生[0] =(P&安培;为0xFF0000)GT;> 16;
先生[1] =(P&安培; 0x00ff00)GT;> 8;
先生[2] =(P&安培; 0x0000ff);
rinsum + =先生[0];
ginsum + =先生[1];
binsum + =先生[2];
率R sum + = rinsum;
GSUM + = ginsum;
bsum + = binsum;
stackpointer =(stackpointer + 1)%DIV;
爵士=栈[(stackpointer)%DIV]。
routsum + =先生[0];
goutsum + =先生[1];
boutsum + =先生[2];
rinsum - =先生[0];
ginsum - =先生[1];
binsum - =先生[2];
易++;
}
YW + = W;
}
为(X = 0; X - 其中;瓦特; X ++){
rinsum = ginsum = binsum = routsum = goutsum = boutsum =率R sum = GSUM = bsum = 0;
YP = -radius *宽;
对于(i = -radius; I< =半径;我++){
YI = Math.max(0,YP)+ X;
爵士=栈[1 +半径]。
爵士[0] = R [易]
爵士[1] = G [易]
爵士[2] = B [易]
RBS = R1 - Math.abs(ⅰ);
率R sum + = R [易] * RBS;
GSUM + = G [易] * RBS;
bsum + = B [易] * RBS;
如果(ⅰ大于0){
rinsum + =先生[0];
ginsum + =先生[1];
binsum + =先生[2];
} 其他 {
routsum + =先生[0];
goutsum + =先生[1];
boutsum + =先生[2];
}
如果(I< HM){
YP + = W;
}
}
易建联= X;
stackpointer =半径;
对于(Y = 0; Y< H; Y ++){
// preserve Alpha通道:(0xff000000&安培; PIX [义])
PIX [易] =(0xff000000和放大器; PIX [义])| (DV [率R sum]其中;&所述; 16)| (DV [GSUM]其中;&所述; 8)| DV [bsum]
率R sum - = routsum;
GSUM - = goutsum;
bsum - = boutsum;
stackstart = stackpointer - 半径+ DIV;
爵士=栈[stackstart%DIV]。
routsum - =先生[0];
goutsum - =先生[1];
boutsum - =先生[2];
如果(X == 0){
VMIN [Y] = Math.min(Y + R1,HM)*宽;
}
P = X + VMIN [Y]
先生[0] = R [P];
先生[1] =克[P];
先生[2] = b的[P];
rinsum + =先生[0];
ginsum + =先生[1];
binsum + =先生[2];
率R sum + = rinsum;
GSUM + = ginsum;
bsum + = binsum;
stackpointer =(stackpointer + 1)%DIV;
爵士=堆叠[stackpointer]
routsum + =先生[0];
goutsum + =先生[1];
boutsum + =先生[2];
rinsum - =先生[0];
ginsum - =先生[1];
binsum - =先生[2];
易建联+ = W;
}
}
Log.e(PIX,W ++ H ++ pix.length);
bitmap.setPixels(PIX,0,瓦特,0,0,W,H);
返回(位);
}
模糊效果总是很难在Android上。从本质上讲,你有外观和性能之间做出选择。更好的模糊看起来它需要的时间越长,如果模糊本身不是瞬间的,那么你真的不能动画模糊。
您最初的模糊算法产生真正的效果不错,但因为它也是制作模糊动画不可能很慢。只是为了演示怎样才能通过缩放位图到有效地模糊了这个图片我创建了一个简单的模糊的动画:
公共类BlurAnimation扩展动画{
私人最终的ImageView ImageView的;
私人最终点阵位图;
私人最终浮在startValue;
私人最终浮动stopValue;
私人最终浮动difValue;
私人BlurAnimation(ImageView的ImageView的,位图位图,诠释在startValue,诠释stopValue){
this.imageView = ImageView的;
this.bitmap =位图;
this.startValue =在startValue;
this.stopValue = stopValue;
this.difValue = stopValue - 在startValue;
}
@覆盖
保护无效applyTransformation(浮动interpolatedTime,变换T){
super.applyTransformation(interpolatedTime,T);
INT电流=(INT)(this.difValue * interpolatedTime + this.startValue + 0.5F);
位图模糊= quickBlur(this.bitmap,电流);
this.imageView.setImageBitmap(模糊);
}
公共位图quickBlur(位图位图,INT因子){
如果(因子VIII; = 0){
返回Bitmap.createBitmap(1,1,Bitmap.Config.ARGB_8888);
}
返回Bitmap.createScaledBitmap(位图,bitmap.getWidth()/因子,bitmap.getHeight()/因素,真正的);
}
}
这工作得很好(尽管仍有一定的滞后性),但结果不能与您的模糊算法相比,它只是看起来可怕的:
所以你看,这是非常困难的,当涉及到图像的模糊结合的性能和良好的外观,但首先是 RenderScript
一些选项。 RenderScript
速度非常快,有一个内置的高斯模糊滤镜。我从来没有用过它,但是从我听到它可能会解决你的问题。
您也可以尝试在加载图像的已按比例缩小的版本,这将产生同样的效果如以上的gif,但甚至会更快。其缺点是,在使用这样的一个动画
再有问题的,但如果你只需要一个模糊的形象,你真的不关心质量,那么你应该去为这个选项
您可以找到有关 RenderScript
了解更多信息和其他快速模糊选项 在这个答案
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.
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.
Can anybody help me out?
EDIT: This is the method I currently have to blur the image.
public Bitmap blur(Bitmap sentBitmap, int radius) {
// Stack Blur Algorithm by Mario Klingemann <[email protected]>
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);
}
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:
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.
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.
You can find more information about RenderScript
and other fast blur options in this answer
这篇关于Android的ImageView的模糊动画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!