#android #bitmap
Есть приложение, в котором используется тема Theme.Wallpaper.NoTitleBar.FullScreen, что позволяет реализовать в качестве фона изображение рабочего стола. Появилась необходимость сделать этот фон размытым. Флаг FLAG_BLUR_BEHIND для WindowManager не подходит, поэтому надумал реализовать программное получение фонового изображения, его размытие и последующую установку на фон. Для этого опробовал два способа. Первый: WallpaperManager wm = WallpaperManager.getInstance(getApplicationContext()); Drawable drawable = wm.getFastDrawable(); Второй: View v1 = ((RelativeLayout) findViewById(R.id.container)).getRootView(); v1.setDrawingCacheEnabled(true); bm = v1.getDrawingCache(); В первом случае использую WallpaperManager для получения фонового изображения рабочего стола. Метод не подходит, т.к. в ответ приходит Bitmap, содержащий все изображение, установленное на обои. Т.е. без обрезки. Во втором случае делаю скриншот экрана приложения. Метод вызываю до установки элементов на Layout, т.е. в тот момент, когда на экране виден только слегка затемненный фон рабочего стола (благодаря теме). Но метод не срабатывает, третья строка возвращает null, хотя и пробовал менять тему. После же компановки экрана метод работает. Что подскажите, как заставить приложение работать как нужно?
Ответы
Ответ 1
Как получить изображение фона (точнее любой View, в нашем случае rootView)? public static Bitmap getBitmapFromView(View view) { Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888); Canvas c = new Canvas(bitmap); view.layout(view.getLeft(), view.getTop(), view.getRight(), view.getBottom()); view.draw(c); return bitamp; } Теперь надо применить Blur к Bitmap (полученному выше)? Для начала инициализируем константы, используемые при создании Blur. private static final float BITMAP_SCALE = 0.5f; // кроп-фактор для исходного изображения private static final float BLUR_RADIUS = 6.0f; // радиус пятна размытия в диапазоне 0 < BLUR_RADIUS <= 25 Так как мы используем ScriptIntrinsicBlur из v8 support library, необходимо будет включить поддержку в gradle файле. android { ... defaultConfig { ... renderscriptTargetApi *your target api* renderscriptSupportModeEnabled true } ... } Теперь сам код для получения Bitmap с эффектом blur, который использует клвссы RenderScript и ScriptIntrinsicBlur: public static Bitmap blur(Context ctx, Bitmap image) { int width = Math.round(image.getWidth() * BITMAP_SCALE); int height = Math.round(image.getHeight() * BITMAP_SCALE); Bitmap inputBitmap = Bitmap.createScaledBitmap(image, width, height, false); Bitmap outputBitmap = Bitmap.createBitmap(inputBitmap); RenderScript rs = RenderScript.create(ctx); ScriptIntrinsicBlur theIntrinsic = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs)); Allocation tmpIn = Allocation.createFromBitmap(rs, inputBitmap); Allocation tmpOut = Allocation.createFromBitmap(rs, outputBitmap); theIntrinsic.setRadius(BLUR_RADIUS); theIntrinsic.setInput(tmpIn); theIntrinsic.forEach(tmpOut); tmpOut.copyTo(outputBitmap); return outputBitmap; } Как связать все вышеописанное? Добавляем описанный ниже код в метод onCreateView() и наслаждаемся результатом. final Activity activity = getActivity(); final View content = activity.findViewById(android.R.id.content).getRootView(); if (content.getWidth() > 0) { Bitmap image = blur(content.getContext(),getBitmapFromView(content)); window.setBackgroundDrawable(new BitmapDrawable(activity.getResources(), image)); } else { content.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() { @Override public void onGlobalLayout() { Bitmap image = blur(content.getContext(),getBitmapFromView(content)); window.setBackgroundDrawable(new BitmapDrawable(activity.getResources(), image)); } }); }
Комментариев нет:
Отправить комментарий