Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


Vista borrosa transparente que difumina el diseño debajo

Tengo un Linearlayout que he hecho transparente, y ahora estoy buscando una manera de darle un efecto Blur, así que lo que está debajo de él se vuelve borroso. Al igual que el aspecto de Windows 7 Aero (ver captura de pantalla).

Sé que puedes hacer un efecto borroso como este:

  • No se puede iniciar Emulator en android studio 2.0
  • Android SQlite problema de fugas con CursorAdapter
  • SSO de Android (inicio de sesión único) para la aplicación
  • Llavero Android para las credenciales de usuario
  • "La versión mínima de Gradle admitida es 2.14.1. La versión actual es 2.10. "Error
  • Android Studio Project dice que el proyecto ya está en GitHub a pesar de que he eliminado el repositorio.
  • getWindow().addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND); 

    Pero esto sólo se aplica a como borrosa el fondo cuando aparece un cuadro de diálogo.

    He estado buscando en Google durante casi una hora, y no encuentro nada. ¿Alguien tiene alguna sugerencia sobre cómo hacer esto?

    Gracias

    Efecto de Windows 7 Aero

  • Android :: findViewByID - ¿cómo puedo obtener la vista de un TextView a través de un Listener de otro elemento de IU?
  • Proveedores de contenido multiproceso sincronizados a uno predeterminado
  • La llamada requiere el nivel 23 de API: error getForeground (), pero es un método FrameLayout ya que API 1
  • ¿Cómo recuperar una lista de fuentes disponibles / instaladas en android?
  • Android: ¿Cómo usar la webcam en el emulador?
  • La fuente personalizada da un glifo incorrecto para ciertas combinaciones de letras en Android
  • 6 Solutions collect form web for “Vista borrosa transparente que difumina el diseño debajo”

    Esto estaba en mi mente durante algún tiempo, y acabo de implementarlo gracias a su pregunta.

    Para poder hacer esto, necesitamos dibujar el diseño que está debajo de nuestro diseño de desenfoque en un mapa de bits. Que mediante el uso de un algoritmo borroso, tenemos que difuminar ese mapa de bits y, finalmente, dibujar mapa de bits borrosa como fondo de nuestro diseño borroso.

    Afortunadamente androide tiene mecanismo de dibujo en caché, por lo que la primera parte es fácil. Podemos simplemente habilitar el dibujo en caché para nuestro diseño debajo y usar getDrawingCache() para adquirir el mapa de bits de él.

    Ahora necesitamos un algoritmo rápido de borrosidad. Utilicé este https://stackoverflow.com/a/10028267/3133545

    Aquí está.

     import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.ColorFilter; import android.graphics.Paint; import android.graphics.PixelFormat; import android.graphics.drawable.Drawable; import android.util.Log; import android.view.View; import java.lang.ref.WeakReference; import java.util.InputMismatchException; /** * A drawable that draws the target view as blurred using fast blur * <p/> * <p/> * TODO:we might use setBounds() to draw only part a of the target view * <p/> * Created by 10uR on 24.5.2014. */ public class BlurDrawable extends Drawable { private WeakReference<View> targetRef; private Bitmap blurred; private Paint paint; private int radius; public BlurDrawable(View target) { this(target, 10); } public BlurDrawable(View target, int radius) { this.targetRef = new WeakReference<View>(target); setRadius(radius); target.setDrawingCacheEnabled(true); target.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_AUTO); paint = new Paint(); paint.setAntiAlias(true); paint.setFilterBitmap(true); } @Override public void draw(Canvas canvas) { if (blurred == null) { View target = targetRef.get(); if (target != null) { Bitmap bitmap = target.getDrawingCache(true); if (bitmap == null) return; blurred = fastBlur(bitmap, radius); } } if (blurred != null && !blurred.isRecycled()) canvas.drawBitmap(blurred, 0, 0, paint); } /** * Set the bluring radius that will be applied to target view's bitmap * * @param radius should be 0-100 */ public void setRadius(int radius) { if (radius < 0 || radius > 100) throw new InputMismatchException("Radius must be 0 <= radius <= 100 !"); this.radius = radius; if (blurred != null) { blurred.recycle(); blurred = null; } invalidateSelf(); } public int getRadius() { return radius; } @Override public void setAlpha(int alpha) { } @Override public void setColorFilter(ColorFilter cf) { } @Override public int getOpacity() { return PixelFormat.TRANSLUCENT; } /** * from https://stackoverflow.com/a/10028267/3133545 * <p/> * <p/> * <p/> * Stack Blur v1.0 from * http://www.quasimondo.com/StackBlurForCanvas/StackBlurDemo.html * <p/> * Java Author: Mario Klingemann <mario at quasimondo.com> * http://incubator.quasimondo.com * created Feburary 29, 2004 * Android port : Yahel Bouaziz <yahel at kayenko.com> * http://www.kayenko.com * ported april 5th, 2012 * <p/> * This is a compromise between Gaussian Blur and Box blur * It creates much better looking blurs than Box Blur, but is * 7x faster than my Gaussian Blur implementation. * <p/> * I called it Stack Blur because this describes best how this * filter works internally: it creates a kind of moving stack * of colors whilst scanning through the image. Thereby it * just has to add one new block of color to the right side * of the stack and remove the leftmost color. The remaining * colors on the topmost layer of the stack are either added on * or reduced by one, depending on if they are on the right or * on the left side of the stack. * <p/> * If you are using this algorithm in your code please add * the following line: * <p/> * Stack Blur Algorithm by Mario Klingemann <mario@quasimondo.com> */ private static Bitmap fastBlur(Bitmap sentBitmap, int radius) { 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; } } bitmap.setPixels(pix, 0, w, 0, 0, w, h); return (bitmap); } } 

    Uso:

     View beneathView = //the view that beneath blur view View blurView= //blur View BlurDrawable blurDrawable = new BlurDrawable(beneathView, radius); blurView.setBackgroundDrawable(blurDrawable); 

    Y cómo se veía mi aplicación de prueba:

    Aplicación de prueba

    Decidí no usar este tho, porque es demasiado hacky y no mirar tan fresco como pensé que estaría en el primer lugar.

    Desdibujarse en tiempo real en android sigue siendo un obstáculo. He aquí una comparación completa entre algunos de los mecanismos viables:

    StackBlur (ya enumerado en la respuesta de Onur bajo el apodo fastBlur ):

    Cómo se ve (en el radio 20):

    Introduzca aquí la descripción de la imagen

    BitmapDrawable registrado (ms) para generar cada BitmapDrawable :

     I/(10266): Total time taken: 35 I/(10266): Total time taken: 54 I/(10266): Total time taken: 48 I/(10266): Total time taken: 36 I/(10266): Total time taken: 48 I/(10266): Total time taken: 39 I/(10266): Total time taken: 49 I/(10266): Total time taken: 50 I/(10266): Total time taken: 35 I/(10266): Total time taken: 47 

    Promedio => ~ 44,1 ms => 22 trazos por segundo

    RenderScript :

    ScriptIntrinsicBlur proporciona un desenfoque consistentemente rápido. Su api disponible 8 en adelante utilizando la biblioteca de soporte.

    Lo que parece (en el radio 20):

    Introduzca aquí la descripción de la imagen

    BitmapDrawable registrado (ms) para generar cada BitmapDrawable :

     I/(9342): Total time taken: 14 I/(9342): Total time taken: 16 I/(9342): Total time taken: 13 I/(9342): Total time taken: 28 I/(9342): Total time taken: 14 I/(9342): Total time taken: 12 I/(9342): Total time taken: 14 I/(9342): Total time taken: 19 I/(9342): Total time taken: 13 I/(9342): Total time taken: 13 

    Promedio => ~ 15,6 ms => 64 trazos por segundo

    RenderScript (radio = 3) + Escala (20%) :

    Esta es otra manera de conseguir un desenfoque decente (?) Pero rápido . Lo que hacemos es escalar el mapa de bits a una fracción de su tamaño, digamos 20%, y aplicar el algoritmo de desenfoque en la versión reducida. Una vez hecho esto, escalamos el mapa de bits a su tamaño original. Los resultados no son tan buenos como usar el algoritmo de desenfoque en el original, pero son aceptables. Observe también que el valor de radio no debe ser demasiado alto o el mapa de bits resultante será indiscernible.

    Lo que parece:

    Introduzca aquí la descripción de la imagen

    BitmapDrawable registrado (ms) para generar cada BitmapDrawable :

     I/(11631): Total time taken: 5 I/(11631): Total time taken: 19 I/(11631): Total time taken: 3 I/(11631): Total time taken: 7 I/(11631): Total time taken: 7 I/(11631): Total time taken: 5 I/(11631): Total time taken: 7 I/(11631): Total time taken: 17 I/(11631): Total time taken: 5 I/(11631): Total time taken: 4 

    Promedio => ~ 7,9 ms => 126 trazos por segundo

    StackBlur (radio = 3) + Escala (20%) :

    El mismo concepto que # 3 arriba. Reduzca el tamaño al 20% y aplique stackblur en el mapa de bits escalado.

    Introduzca aquí la descripción de la imagen

     I/(12690): Total time taken: 4 I/(12690): Total time taken: 20 I/(12690): Total time taken: 4 I/(12690): Total time taken: 4 I/(12690): Total time taken: 5 I/(12690): Total time taken: 5 I/(12690): Total time taken: 4 I/(12690): Total time taken: 21 I/(12690): Total time taken: 3 I/(12690): Total time taken: 4 

    Promedio => ~ 7,4 ms => 135 trazos por segundo

    Ensayos realizados en Nex4. Tamaño de mapa de bits – 200px x 200px

    Otro consejo : los métodos buildDrawingCache() y getDrawingCache() toman mucho tiempo. Una alternativa a esto es crear un mapa de bits utilizando las dimensiones de la vista que necesita desenfocar:

     Bitmap toDrawOn = Bitmap.createBitmap(viewWidth, viewHeight, Bitmap.Config.ARGB_8888); // Create a canvas - assign `toDrawOn` as an offscreen bitmap to it Canvas holdingCanvas = new Canvas(toDrawOn); // Now, let the view draw itself on this canvas yourView.draw(holdingCanvas); 

    La vista ahora se dibuja en toDrawOn y usted puede utilizarla sin embargo usted por favor.

    Esto, en mi experiencia, es mucho más rápido que generar y acceder a la caché de dibujo de una vista.

    Si necesita ayuda para implementar cualquiera de los 4 métodos enumerados anteriormente, hágamelo saber en los comentarios.

    Tenga en cuenta que los gifs anteriores han sido reducidos y whatnot. Si desea ver los archivos originales de captura de pantalla (mp4), marque este enlace .

    Esta es una buena manera de "Blur Images Efficiently using Renderscript" de GDE Mario Viviani .

    Aquí está la copia / pega:

    Las imágenes borrosas son un efecto que muchos desarrolladores necesitan lograr, y puede requerir algún tiempo y esfuerzos para implementarse. Además, puesto que se requiere mucha manipulación de imágenes, si no se codifica apropiadamente, puede ser realmente un dolor en términos de uso de memoria y CPU.

    Hay una solución rápida y eficiente para desenfocar imágenes, que es Renderscript .

    Disponible desde la API 11 ( Honeycomb ), Renderscript permite aprovechar la aceleración de la GPU y está dirigido a renderizado 3D de alto rendimiento y operaciones de cálculo. Renderscript es un producto realmente complejo y articulado, que permite una profunda configuración y codificación utilizando el lenguaje nativo C99, que permite la portabilidad, el rendimiento y la facilidad de uso.

    Sin embargo, dado que la API 17 (4.2.2) Renderscript ofrece algunas funciones incorporadas que realizan operaciones bien definidas, llamadas Intrinsics. Intrinsics son scripts pre-escritos que permiten realizar operaciones como Blur, Blen, Matrix Convolution y más, sin necesidad de escribir código Renderscript .

    Aquí está un método simple que escribí para terminar fácilmente aplican eficientemente un filtro de la falta de definición a un mapa de bits:

     public Bitmap blurBitmap(Bitmap bitmap) { //Let's create an empty bitmap with the same size of the bitmap we want to blur Bitmap outBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888); //Instantiate a new Renderscript RenderScript rs = RenderScript.create(getApplicationContext()); //Create an Intrinsic Blur Script using the Renderscript ScriptIntrinsicBlur blurScript = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs)); //Create the in/out Allocations with the Renderscript and the in/out bitmaps Allocation allIn = Allocation.createFromBitmap(rs, bitmap); Allocation allOut = Allocation.createFromBitmap(rs, outBitmap); //Set the radius of the blur blurScript.setRadius(25.f); //Perform the Renderscript blurScript.setInput(allIn); blurScript.forEach(allOut); //Copy the final bitmap created by the out Allocation to the outBitmap allOut.copyTo(outBitmap); //recycle the original bitmap bitmap.recycle(); //After finishing everything, we destroy the Renderscript. rs.destroy(); return outBitmap; } 

    Imagen borrosa de RenderScript

    Y … voilà! Bitmap borroso! Todos los derechos reservados

    Recuerde que para ejecutar el código anterior necesita API 17 (4.2.2).

    He aquí un resumen de este método: https://gist.github.com/Mariuxtheone/903c35b4927c0df18cf8

    Si quieres descubrir más sobre Intrinsics, echa un vistazo a este post en Android Developers Blog: http://android-developers.blogspot.it/2013/08/renderscript-intrinsics.html

    Si estás interesado en saber más sobre Renderscript, echa un vistazo a estos enlaces: http://android-developers.blogspot.it/2011/02/introducing-renderscript.html http://android-developers.blogspot.it/2011 /03/renderscript.html

    No es posible hacerlo con facilidad, usando las funciones de diseño.

    Yo sugeriría el dibujo a los padres de vista de lienzo como se describe aquí: ¿Cómo hacer que cualquier vista para dibujar a la lona? Con la vista en primer plano oculta. A continuación, desenfocar el lienzo y dibujar la vista en primer plano utilizando estos datos como fondo o parte de él.

    Será operación muy intensiva de recursos si desea que este efecto sea en vivo. Debería al menos intentar almacenar en caché el resultado de desenfoque.

    Intenta usar esta biblioteca creo que solo necesitas pasar la vista sobre ella y funcionará …

    https://github.com/kikoso/android-stackblur

    Paso 1. cortar la parte de la imagen de fondo en el mapa de bits que debe ser blured.

    Paso 2. Desdibuja esa parte del mapa de bits.

    Paso 3. Establecer mapa de bits como fondo.

    Método java

     private void applyBlur(final View image, final View layout) { image.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { image.getViewTreeObserver().removeOnPreDrawListener(this); image.buildDrawingCache(); Bitmap bmp = image.getDrawingCache(); Bitmap overlay = Bitmap.createBitmap((int) (layout.getMeasuredWidth()), (int) (layout.getMeasuredHeight()), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(overlay); canvas.translate(-layout.getLeft(), -layout.getTop()); canvas.drawBitmap(bmp, 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(20); blur.forEach(overlayAlloc); overlayAlloc.copyTo(overlay); layout.setBackground(new BitmapDrawable( getResources(), overlay)); rs.destroy(); return true; } }); } 

    Ahora llamar a esta función:

    Método de llamada

    ApplyBlur (detail_main_image, titleLayout);

    // donde detail_main_image es la imagen en la que tengo que mostrar la parte de desenfoque // y titleLayout es la vista en la que tengo que definir el desenfoque de fondo.

    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.