Страницы

Поиск по вопросам

пятница, 27 декабря 2019 г.

Получение фонового изображения, Android

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

Комментариев нет:

Отправить комментарий