Intereting Posts
Как реализовать базу данных SQLite в Phonegap? Имея несколько SQLiteOpenhelper в одном приложении Android Разрешение отказа: startActivity запрашивает запуск как пользователь -2, но вызывает от пользователя 0; Это требует android.permission.INTERACT_ACROSS_USERS_FULL Android – Виджет с прокручиваемым списком Manual Refresh Раздел Indexer Overlay не обновляется по мере изменения данных адаптера Проверьте, доступно ли ури-ури Как разбираться с GSON, когда идентификатор имеет место в имени Запуск службы android с использованием явного или неявного намерения Расширение класса Приложение бросает ClassNotFoundException Android: CursorLoader, LoaderManager, SQLite Если ScrollView поддерживает только один прямой дочерний элемент, как я могу сделать весь макет прокручиваемым? Не удалось создать приложение Android FabricGenerateResourcesDebug ZXing на Android PDF417 Исправление ошибок Eclipse при использовании Android NDK и std :: vector Android NDK: Прекратить остановку?

Прозрачный размытый вид, который размывает макет под

У меня есть Linringayout, который я сделал прозрачным, и теперь я ищу способ дать эффект Blur, так что что-то под ним размыто. Так же, как и Windows 7 Aero (см. Снимок экрана).

Я знаю, что вы можете сделать эффект размытия следующим образом:

getWindow().addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND); 

Но это относится только к тому, чтобы размывать фон при появлении диалогового окна.

Я уже почти час искал в Интернете, и ничего не могу найти. У кого-нибудь есть предложения по тому, как это сделать?

благодаря

Эффект A7 для Windows 7

Solutions Collecting From Web of "Прозрачный размытый вид, который размывает макет под"

Это было на мой взгляд в течение некоторого времени, и я только что реализовал это благодаря вашему вопросу.

Чтобы иметь возможность сделать это, нам нужно нарисовать макет, который находится ниже нашего размытия, в растровое изображение. Затем, используя алгоритм размытия, мы должны размыть это растровое изображение и, наконец, нарисовать размытое растровое изображение в качестве фона нашего размытия.

К счастью, андроид имеет кэшированный механизм рисования, поэтому первая часть проста. Мы можем просто включить кешированный чертеж для нашего макета и использовать getDrawingCache() для получения растрового изображения.

Теперь нам нужен быстрый алгоритм размытия. Я использовал этот https://stackoverflow.com/a/10028267/3133545

Вот.

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

Применение :

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

И как мое тестовое приложение выглядело так:

Тестовое приложение

Я решил не использовать этот tho, потому что он слишком хакерский и выглядит не так круто, как я думал, что это будет на первом месте.

Размытие в реальном времени на андроиде по-прежнему является препятствием. Вот всестороннее сравнение некоторых из жизнеспособных механизмов:

StackBlur (уже указан в ответе Onur под fastBlur ):

Как это выглядит (в радиусе 20):

Введите описание изображения здесь

Записанное время (мс) для генерации каждого 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 

Среднее => ~ 44,1 мс => 22 оборота в секунду

RenderScript :

ScriptIntrinsicBlur обеспечивает стабильно быстрое размытие. Его доступный api 8 с помощью библиотеки поддержки.

Как это выглядит (при радиусе 20):

Введите описание изображения здесь

Записанное время (мс) для генерации каждого 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 

Среднее => ~ 15,6 мс => 64 числа в секунду

RenderScript (радиус = 3) + Масштабирование (20%) :

Это еще один способ получить приличное (?), Но быстрое размытие. Мы делаем масштабирование растрового изображения до части его размера – скажем, 20% – и применяем алгоритм размытия в уменьшенной версии. Как только это будет сделано, мы масштабируем растровое изображение до его первоначального размера. Результаты не так хороши, как использование алгоритма размытия на оригинале, но они проходимы. Также обратите внимание на то, что значение радиуса не должно быть слишком высоким или итоговое растровое изображение будет неразличимым.

На что это похоже:

Введите описание изображения здесь

Записанное время (мс) для генерации каждого 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 

Среднее => ~ 7.9 мс => 126 выходов в секунду

StackBlur (радиус = 3) + Масштабирование (20%) :

Та же концепция, что и № 3 выше. Уменьшите размер до 20% и примените stackblur на масштабированном растровом изображении.

Введите описание изображения здесь

 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 

Среднее => ~ 7.4 мс => 135 обратных в секунду

Тесты, проведенные на Nex4. Размер растрового изображения – 200 пикселей x 200 пикселей

Другой совет : методы buildDrawingCache() и getDrawingCache() сами занимают много времени. Альтернативой этому является создание растрового изображения с использованием размеров представления, которое нужно размыть:

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

Теперь вид нарисован на toDrawOn и вы можете использовать его, как вам угодно.

Это, по моему опыту, намного быстрее, чем генерация и доступ к кешу чертежа представления.

Если вам нужна помощь в реализации любого из перечисленных выше четырех методов, дайте мне знать в комментариях.

Имейте в виду, что приведенные выше gifs были уменьшены и еще много чего. Если вы хотите увидеть исходные файлы для захвата экрана (mp4) – проверьте эту ссылку .

Вот хороший способ «Размытия изображений, эффективно использующих Renderscript» GDE Марио Вивиани .

Вот копирование / вставка:

Размытие изображений – это эффект, который многие разработчики должны достичь, и для его выполнения может потребоваться некоторое время и усилия. Кроме того, поскольку требуется много манипуляций с изображениями, если это не правильно закодировано, это может быть очень больно с точки зрения использования ЦП и памяти.

Существует быстрое и эффективное решение для размытия изображений, которое представляет собой Renderscript .

Доступный с API 11 ( Honeycomb ), Renderscript позволяет использовать ускорение GPU и ориентирован на высокопроизводительные 3D-рендеринг и вычисления. Renderscript – действительно сложный и сочлененный продукт и позволяет осуществлять глубокую настройку и кодирование с использованием родного языка C99, который позволяет переносить, производительность и удобство использования.

Однако, поскольку API 17 (4.2.2) Renderscript предлагает некоторые встроенные функции, которые выполняют четко определенные операции, называемые Intrinsics. Intrinsics – это предварительно написанные сценарии, позволяющие выполнять такие операции, как Blur, Blen, Matrix Convolution и т. Д., Без необходимости писать код Renderscript .

Вот простой способ, который я написал, чтобы легко закончить эффективно применять фильтр Blur к Bitmap:

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

Размытое изображение RenderScript

И … вуаля! Размытое растровое изображение! 🙂

Помните, что для запуска предыдущего кода вам потребуется минимум API 17 (4.2.2).

Вот суть этого метода: https://gist.github.com/Mariuxtheone/903c35b4927c0df18cf8

Если вы хотите узнать больше об Intrinsics, ознакомьтесь с этим сообщением в блоге разработчиков Android: http://android-developers.blogspot.it/2013/08/renderscript-intrinsics.html

Если вам интересно узнать больше о Renderscript, ознакомьтесь с этими ссылками: http://android-developers.blogspot.it/2011/02/introducing-renderscript.html http://android-developers.blogspot.it/2011 /03/renderscript.html

Это невозможно сделать легко, используя функции компоновки.

Я бы предложил рисовать родительский вид на холст, как описано здесь: Как сделать любое изображение для рисования на холст? С закрытым передним планом. Затем размыте холст и нарисуйте представление переднего плана, используя эти данные в качестве фона или его части.

Это будет очень ресурсоемкая операция, если вы хотите, чтобы этот эффект был вживую. Вы должны хотя бы попробовать кэшировать результат размытия.

Попытайтесь использовать эту библиотеку, я думаю, вам просто нужно передать представление на нее, и она будет работать …

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

Шаг 1. разрежьте часть фонового изображения в растровом изображении, которое должно быть размыто.

Шаг 2. Размываем ту часть растрового изображения.

Шаг 3. Установите растровое изображение в качестве фона.

Метод 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; } }); } 

Теперь вызовите эту функцию:

Метод вызова

ApplyBlur (detail_main_image, titleLayout);

// где detail_main_image – это изображение, на котором я должен показать часть размытия // и titleLayout – это представление, на котором я должен установить размытие фона.