我想在
ImageView中添加模糊动画,但设置持续时间.所以,例如,我希望图像随着时间的推移而模糊.
我已经有了模糊图像的方法,但我需要的是让它从模糊变为无模糊,比如2秒.
有人可以帮帮我吗?
编辑:这是我目前模糊图像的方法.
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,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,h); return (bitmap); }
解决方法
Android上的模糊效果总是很难.基本上你必须在外观和性能之间做出决定.模糊看起来越长越好,如果模糊本身不是瞬间的,那么你就无法真正为模糊设置动画.
你原始的模糊算法产生了非常好的结果,但由于这一点,它也很慢,使模糊动画不可能.为了演示如何有效地模糊这个图像,我通过缩放位图来创建一个简单的模糊动画:
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); } }
这很有效(即使仍有一些滞后),但结果无法与您的模糊算法进行比较,它看起来很糟糕:
所以你看,在模糊图像时很难将性能和美观结合起来,但有一些选项首先是RenderScript. RenderScript速度非常快,并且内置高斯模糊滤镜.我从来没有使用它,但从我听到它可能是你的问题的解决方案.
您还可以尝试加载图像的已缩小版本,这将产生与上面的gif相同的效果,但会更快.缺点是在动画中使用它也是有问题的,但是如果你只是需要一个模糊的图像而你并不真正关心质量,那么你应该选择这个选项.
您可以找到有关RenderScript和其他快速模糊选项in this answer的更多信息