Blur linear layout background - android

In my app I have a LinearLayout which is transparent and it is attached to WindowManager .I want to make that LinearLayout Blur so that everything behind the LinearLayout will look blurred.I had gone through various sources from that I had got how to make a ImageView blur and I had done that successfully using RenderScript Api here is the code:
private static final float BLUR_RADIUS = 25f;
Bitmap outputBitmap = Bitmap.createBitmap(image);
final RenderScript renderScript = RenderScript.create(this);
Allocation tmpIn = Allocation.createFromBitmap(renderScript, image);
Allocation tmpOut = Allocation.createFromBitmap(renderScript, outputBitmap);
//Intrinsic Gausian blur filter
ScriptIntrinsicBlur theIntrinsic = ScriptIntrinsicBlur.create(renderScript, Element.U8_4(renderScript));
theIntrinsic.setRadius(BLUR_RADIUS);
theIntrinsic.setInput(tmpIn);
theIntrinsic.forEach(tmpOut);
tmpOut.copyTo(outputBitmap);
return outputBitmap;
}
and finally adding it with `ImageView`
ImageView imageView=(ImageView)findViewById(image-id);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.nature);
Bitmap blurredBitmap = blur(bitmap);
imageView.setImageBitmap(blurredBitmap);
but sadly it blurs ImageView only.Any solution for blurring a layout or modifiying the above code to use it with Layout.
Hi everyone I had got to know how to blur an ImageView successfully but how can I blur an transparent LinearLayout.Is there any solution for this please help me

I created an example project to give an example of a possible process to use (main code).
The purpose of this example is to show how RenderScript can be used to blur a generic view.
What the example does (when the button "Blur it!" gets clicked) is:
1) Blurs the chosen view
The chosen view, for this example, must be contained inside a bigger container (ex. a LinearLayout).
The blur process:
Gets a screenshot of the original view.
Bitmap getViewScreenshot(View v) {
v.setDrawingCacheEnabled(true);
Bitmap b = Bitmap.createBitmap(v.getDrawingCache());
v.setDrawingCacheEnabled(false);
return b;
}
Instantiates all RenderScript allocations (one for input and one for blur output).
allocOriginalScreenshot = Allocation.createFromBitmap(mRS, viewScreenshot);
// Creates an allocation where to store the blur results
allocBlurred = Allocation.createTyped(mRS, allocOriginalScreenshot.getType(), Allocation.USAGE_SCRIPT | Allocation.USAGE_IO_OUTPUT);
Creates a TextureView to display the blur result.
Substitutes the new TextureView with the original view. In this process, the new view gets saved inside the "tag" field of the original view, so that later the original view can be substituted back with the new TextureView.
void replaceView(View originalView, View newView) {
originalView.setTag(newView);
newView.setLayoutParams(new FrameLayout.LayoutParams(originalView.getLayoutParams()));
ViewGroup parent = (ViewGroup) originalView.getParent();
int index = parent.indexOfChild(originalView);
parent.removeView(originalView);
parent.addView(newView, index);
}
Blurs the screenshot using the ScriptIntrinsicBlur class.
void executeBlur() {
Log.d(TAG, "Executing blur");
scriptIntrinsicBlur.setInput(allocOriginalScreenshot);
scriptIntrinsicBlur.forEach(allocBlurred);
allocBlurred.ioSend();
}
2) Display a simple dialog
3) Unblur the original view
The unblur process removes the TextureView from the layout and restores the original View.
Reference: RenderScript: parallel computing on Android, the easy way, Dali library

Related

Android 2D canvas game - draw background bitmap

I'm developing a simple 2D Android game and I want to draw the background of each level when the level begins. The background will be static for each level, it won't animate or move.
At first, I was drawing the background in a custom view using canvas and I was loading that view as the background of the level. That worked, however I noticed that if I draw a lot of lines and shapes, the UI begins to stutter. I solved the problem by drawing the background via canvas and saving it directly into a bitmap, which I then load into a background ImageView as you can see below:
CustomView bgView = new CustomView(this); //this view draws the background
Bitmap bitmap = Bitmap.createBitmap(screenWidth, screenHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
bgView.draw(canvas);
ImageView imageViewBg = (ImageView) findViewById(R.id.imageViewBg);
imageViewBg.setImageBitmap(bitmap);
The problem that I notice with this approach is that I'm creating a bitmap with a size of [screenWidth x screenHeight] which might cause an OutOfMemoryError.
So, what's the best approach for drawing the background of a full-screen game? The problem is that I want to draw it dynamically, I cannot load it directly from the assets. (I could use the Bitmap.Config.RGB_565 profile, but still it will just reduce the size of the bitmap in half, it's not the optimal solution).
I use Bitmap.createScaledBitmap():
Bitmap b = Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.background),WIDTH,HEIGHT,false);
Get the width and height of the screen
Then draw it as usual:
canvas.drawBitmap(b, 0, 0, null);
EDIT:
Load the bitmap any way you would like. For the purposes of the example, the Bitmap-object will be called b. So first:
WIDTH = b.getWidth();
HEIGHT = b.getHeight();
Move on to rendering:
public void render(Canvas c){
final float scaleFactorX = getWidth()/(WIDTH*1.f);
final float scaleFactorY = getHeight()/(HEIGHT*1.f);
//check if the canvas is null first.
int savedState = c.getSaveCount();
c.scale(scaleFactorX, scaleFactorY);
//draw your bitmap.
c.restoreToCount();
//Do normal rendering
}
Explanation
What I do here is to scale the rendering only for the bitmap. This means anything else rendered will not be affected by this.
We need to get the scale factors to scale the screen to when rendering the Bitmap:
final float scaleFactorX = getWidth()/(WIDTH*1.f);
final float scaleFactorY = getHeight()/(HEIGHT*1.f);
Then save the state of the canvas to reload later.
int savedState = c.getSaveCount();
Now we scale the bitmap using the scaleFactors previously defined
c.scale(scaleFactorX, scaleFactorY);
And restore the bitmap to its original state to draw everything else in whatever type of scale you need. If you do not need to zoom the bitmap(if you have zoom) you can add that scaling after the background-scaling.
c.restoreToCount();

Blur effect on background

I need to show something like this in an ImageView
Do you know a method to set an image in an ImageView like so?
Image in background is bluerd and image on it is with blur effect
ImageView imageView=(ImageView)findViewById(R.id.imageView2);
imageView.setImageBitmap(bitmap);
I need put in bitmap my picture and fuzzy picture in background.
this only sets one picture and I need put some fuzzy background
I know how put only one image in 100% quality.
But I don't know how set the background image to this picture.
I don't know how this "filter" name and I could not Google for that.
From https://stackoverflow.com/a/36193733:
I recently came across Renderscript API.
//Set the radius of the Blur. Supported range 0 < radius <= 25
private static final float BLUR_RADIUS = 25f;
public Bitmap blur(Bitmap image) {
if (null == image) return null;
Bitmap outputBitmap = Bitmap.createBitmap(image);
final RenderScript renderScript = RenderScript.create(this);
Allocation tmpIn = Allocation.createFromBitmap(renderScript, image);
Allocation tmpOut = Allocation.createFromBitmap(renderScript, outputBitmap);
//Intrinsic Gausian blur filter
ScriptIntrinsicBlur theIntrinsic = ScriptIntrinsicBlur.create(renderScript, Element.U8_4(renderScript));
theIntrinsic.setRadius(BLUR_RADIUS);
theIntrinsic.setInput(tmpIn);
theIntrinsic.forEach(tmpOut);
tmpOut.copyTo(outputBitmap);
return outputBitmap;
}
Use the above code snippet in the image view as shown below.
ImageView imageView = (ImageView) findViewById(R.id.imageView);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.nature);
Bitmap blurredBitmap = blur(bitmap);
imageView.setImageBitmap(blurredBitmap);
Dont forget to add below lines in build.gradle file
renderscriptTargetApi 18
renderscriptSupportModeEnabled true
You can use View Pager and Add ImageView in each page, that way you can switch between images,
Set your fuzzy/blurry image as the background, using
android:background = "#drawable/myFuzzyImage"
Set your clear image as you would normally, just like you have, using the setImageBitmap, or using an ImageView in the xml file of your activity layout.

How to take screenshot of layout with extra part as transparent not black in android

Current i m doing one image editing android app in which i need to take screenshot of one relative layout My code:
public Bitmap takeScreenshot() {
Bitmap bitTmp;
View rootView = findViewById(R.id.rl_img_view);
rootView.setDrawingCacheEnabled(true);
bitTmp = rootView.getDrawingCache();
return bitTmp;
}
my problem is that when i take screenshot it send me bitmap which contain empty part of layout as black color.
Is it possible to get that empty part transparent on output bitmap?
Output i get: http://postimg.org/image/5mxznc6jv
Output i want: http://postimg.org/image/50bre04kf
Change the width of the bitmap you are gettting, or maybe add padding from left.
Use this :
Public Bitmap pad(Bitmap Src, int padding_x, int padding_y){
Bitmap outputimage = Bitmap.createBitmap(Src.getWidth() + padding_x,Src.getHeight() + padding_y, Bitmap.Config.ARGB_8888);
Canvas can = new Canvas(outputimage);
can.drawARGB(FF,FF,FF,FF); //This represents White color
can.drawBitmap(Src, padding_x, padding_y, null);
return outputimage;
}
Refer to this question : Canvas Bitmap

How to programmatically overlap alpha blended bitmaps in android?

I need to "compute" the resulting bitmap obtained from overlapping two different bitmaps that have an alpha value somewhere between 0 and 255. I need to do this in java code, not xml, because bitmaps are being loaded dinamically and not from resources.
Here is my first try (which always yields a black bitmap...):
private Drawable composeBitmaps(int alpha1, BitmapDrawable bm1,
int alpha2, BitmapDrawable bm2)
{
Canvas c = new Canvas();
Bitmap b1 = bm1.getBitmap();
BitmapDrawable draw1 = new BitmapDrawable(b1.copy(b1.getConfig(), true));
draw1.setAlpha(alpha1);
c.setBitmap(draw1.getBitmap());
Paint p = new Paint();
p.setAlpha(alpha2);
c.drawBitmap(bm2.getBitmap(), 0, 0, p);
return draw1;
}
...
View v = // whatever
v.setBackgroundDrawable(composeBitmaps(100, bdrawable1, 150, bdrawable2));
And the view goes black background. What am I doing wrong?
My code above is absolutely correct. The bug that made the bitmap go black was elsewhere. Found it, fixed it, now it works.
The only thing to note is that my code is slow as hell and it cannot be used to crossfade two fullscreen bitmaps at a reasonable fps rate.

Applying an overlay (image filter) to a Bitmap

I am trying to capture an image from the camera intent and then apply an image filter on it. To elaborate the image would be an image captured by the camera and the image filter would be available in the resources as a png file. I am able to overlay the filter on top of the original image. But, once overlay-ed the original image is 'almost' invisible (which means that the filter is infact being stacked on the original image and not merely replacing it). I have a couple of images to illustrate my problem. The first image was in Photoshop - when I placed a filter on top of an image, it seemed just fine. The second image is the produced by the code cited below - you can clearly see that the filter effect is missing. Would someone have a clue as to why something like this is occurring. Am I missing some logic here?
The following is the code that I have. I apologize if you find any best practices missing here. I am initially trying to test the code:
mPictureView = (ImageView) findViewById(R.id.pictureView);
filterButton = (Button) findViewById(R.id.filter_button1);
// define the threshold fro scaling the image
private final double SCALE_THRESHOLD = 6.0;
// acquire the bitmap (photo captured) from the Camera Intent - the uri is
// passed from a previous activity that accesses the camera and the current
// activity is used to display the bitmap
Uri imageUri = getIntent().getData();
Bitmap imageBitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imageUri);
// set the imageView in the current activity to display the picture retrieved
// from the camera
mPictureView.setImageBitmap(imageBitmap);
// get the dimensions of the original bitmap
int photoWidth = imageBitmap.getWidth();
int photoHeight = imageBitmap.getHeight();
filterButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// set the options
Options options = new BitmapFactory.Options();
options.inScaled = false;
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
// get the image (png file) filter from resources using the options
Bitmap filter = BitmapFactory.decodeResource(getResources(), R.drawable.colorful_filter,options);
// create a scaled copy of the filter
Bitmap filtercopy = Bitmap.createScaledBitmap(filter, (int)(photoWidth/SCALE_THRESHOLD,(int)(photoHeight/SCALE_THRESHOLD), true);
// recycle the used bitmap
filter.recycle();
filter = null;
// get a scaled, mutable copy of the orginial image
Bitmap imagecopy = Bitmap.createScaledBitmap(imageBitmap,(int)(photoWidth/SCALE_THRESHOLD), (int)(photoHeight/SCALE_THRESHOLD),true);
// recycle the used bitmap
imageBitmap.recycle();
imageBitmap = null;
Paint paint = new Paint();
paint.setAntiAlias(true);
//paint.setAlpha(230); - if a discrete value is set, then the image beneath
// the filter is visible. But, I don't understand why I need to do this.
// Besides, that reduces the efficacy of the filter
// create a canvas with the original image as the underlying image
Canvas canvas = new Canvas(imagecopy);
// now, draw the filter on top of the bitmap
canvas.drawBitmap(filtercopy, 0, 0, paint);
// recycle the used bitmap
filtercopy.recycle();
filtercopy = null;
//set the filtered bitmap as the image
mPictureView.setImageBitmap(imagecopy);
}
EDIT 1: I was able to make some progress with the help of the article that Joru has provided. The problem seems to be with blending of the 2 bitmaps. The method drawBitmap would just draw one bitmap over the other in the situation that I have. The following line of code will actually attempt to blend the 2 bitmaps. I have also attached an image which depicts my progress. The underlying bitmap is noticeably more visible now:
paint.setXfermode(new PorterDuffXfermode(Mode.MULTIPLY));
I have to still play around with it for some time, before achieving the desired output.
You could try a few things:
Bitmap new = old.copy(Config.ARGB_8888, true);
To make sure the bitmap you are opening from MediaStore is in that format. If it isn't, that is likely to cause your problem.

Categories

Resources