I would like to have blurred background in ImageView.
I have this, but everything is blurred, both image and the background:
...
imageView.setImageBitmap(bitmapWithoutBlur);
Bitmap bitmapBlur = blur(getApplicationContext(), bitmapWithoutBlur);
BitmapDrawable bitmapDrawable = new BitmapDrawable(getResources(), bitmapBlur);
imageView.setBackgroundDrawable(bitmapDrawable);
...
public static Bitmap blur(Context context, Bitmap bitmap) {
int width = Math.round(bitmap.getWidth());
int height = Math.round(bitmap.getHeight());
Bitmap inputBitmap = Bitmap.createScaledBitmap(bitmap, width, height, false);
Bitmap outputBitmap = Bitmap.createBitmap(inputBitmap);
RenderScript rs = RenderScript.create(context);
ScriptIntrinsicBlur theIntrinsic = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
Allocation tmpIn = Allocation.createFromBitmap(rs, inputBitmap);
Allocation tmpOut = Allocation.createFromBitmap(rs, outputBitmap);
theIntrinsic.setRadius(25f);
theIntrinsic.setInput(tmpIn);
theIntrinsic.forEach(tmpOut);
tmpOut.copyTo(outputBitmap);
return outputBitmap;
}
//In here you have a bitmap without blur
//delete this setting bitmap
//imageView.setImageBitmap(bitmapWithoutBlur);
// Edited lines from here
Bitmap bitmapToBlur = bitmapWithoutBlur;
Bitmap bitmapBlur = blur(getApplicationContext(), bitmapToBlur);
Canvas canvas = new Canvas(BitmapBlur);
canvas.drawBitmap(bitmapToBlur,0f,0f,null);
imageView.setImageBitmap(bitmapToBlur);
In your code look at the commend lines that i wrote.In the second line you make both of the images blurred.Just send bitmapwithoutblur to method and before sending it,use a temp value to withoutblurred version.
Use ScriptIntrinsicBlur from the RenderScript library to blur quickly.Follow this to how to access the RenderScript API http://developer.android.com/guide/topics/renderscript/compute.html#access-rs-apis. The following is a class I made to blur Views and Bitmaps:
public class BlurBuilder {
private static final float BITMAP_SCALE = 0.4f;
private static final float BLUR_RADIUS = 7.5f;
public static Bitmap blur(View v) {
return blur(v.getContext(), getScreenshot(v));
}
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;
}
private static Bitmap getScreenshot(View v) {
Bitmap b = Bitmap.createBitmap(v.getWidth(), v.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
v.draw(c);
return b;
}
}
Related
I am trying to build a simple game on android and while setting the background image and other image assets on my main screen it is appearing too big as shown in the below image.
The actual size of the image is 1920x1080 and I want it to fit my screen like the image shown below:
The code for I have used is:
public class PoliceView extends View {
private Bitmap police;
private Bitmap background;
private Paint scorePaint = new Paint();
private Bitmap life[] = new Bitmap[2];
public PoliceView(Context context) {
super(context);
police = BitmapFactory.decodeResource(getResources(),R.drawable.police);
background = BitmapFactory.decodeResource(getResources(),R.drawable.gamebackground);
scorePaint.setColor(Color.BLACK);
scorePaint.setTextSize(70);
scorePaint.setTypeface(Typeface.DEFAULT_BOLD);
scorePaint.setAntiAlias(true);
life[0] = BitmapFactory.decodeResource(getResources(),R.drawable.heart);
life[1] = BitmapFactory.decodeResource(getResources(),R.drawable.brokenheart);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//The order of draw matters as objects are drawn in this same order
canvas.drawBitmap(background,0,0,null);
canvas.drawBitmap(police, 0, 0, null);
canvas.drawText("Score:",20, 60, scorePaint);
//Three lives for the police
canvas.drawBitmap(life[0],580, 10, null);
canvas.drawBitmap(life[0],680, 10, null);
canvas.drawBitmap(life[0],780, 10, null);
}}
How can I resize the images to fit the screen??
i use this code for resize image
Bitmap tmp = BitmapFactory.decodeFile(mPath);
ResizeWidth = (int) (your size);
ResizeHeight = (int) (your size);
Bitmap bitmap = Bitmap.createBitmap(ResizeWidth, ResizeHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Bitmap scaled = Bitmap.createScaledBitmap(tmp, ResizeWidth, ResizeHeight, true);
int leftOffset = 0;
int topOffset = 0;
canvas.drawBitmap(scaled, leftOffset, topOffset, null);
How to resize bitmap in canvas?
canvas.save(); // Save current canvas params (not only scale)
canvas.scale(scaleX, scaleY);
canvas.restore(); // Restore current canvas params
scale = 1.0f will draw the same visible size bitmap
I have seen many answers on stackoverflow and tried many possible combinations but still i can't get the expected bllureed image as shown below:
Side Blur Edges
The code i tried (using canvas and then overlaying bot images)
public static Bitmap blur(Context context, Bitmap image) {
int width = Math.round(image.getWidth());
int height = Math.round(image.getHeight());
Bitmap inputBitmap = Bitmap.createScaledBitmap(image, width, height, false);
Bitmap outputBitmap = Bitmap.createBitmap(inputBitmap);
RenderScript rs = RenderScript.create(context);
ScriptIntrinsicBlur theIntrinsic = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
Allocation tmpIn = Allocation.createFromBitmap(rs, inputBitmap);
Allocation tmpOut = Allocation.createFromBitmap(rs, outputBitmap);
theIntrinsic.setRadius(25);
theIntrinsic.setInput(tmpIn);
theIntrinsic.forEach(tmpOut);
tmpOut.copyTo(outputBitmap);
return outputBitmap;
}
public static Bitmap overlayBitmap(Bitmap bitmapBackground, Bitmap bitmapImage) {
Bitmap resized_bitmap = Bitmap.createScaledBitmap(bitmapImage, (int) (bitmapBackground.getWidth()*0.8), bitmapBackground.getWidth(),true);
Bitmap bmOverlay = Bitmap.createBitmap(bitmapBackground.getWidth(), bitmapBackground.getHeight(), bitmapBackground.getConfig());
Canvas canvas = new Canvas(bmOverlay);
canvas.drawBitmap(bitmapBackground, new Matrix(), null);
canvas.drawBitmap(resized_bitmap,bitmapBackground.getWidth()/5,bitmapBackground.getHeight()/5, null);
return bmOverlay;
}
Not getting the desired blur using this code tried several combinations but still no success.
When Trying to blur out both sides of my ImageView I used the following code:
private void applyBlur(final ImageView image) {
image.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
#Override
public boolean onPreDraw() {
image.getViewTreeObserver().removeOnPreDrawListener(this);
image.buildDrawingCache();
Bitmap bmp = image.getDrawingCache();
blur(bmp, image);
return true;
}
});
}
#TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
private void blur(Bitmap mBitmap, View view) {
long startMs = System.currentTimeMillis();
float radius = 20;
Bitmap overlay = Bitmap.createBitmap((int) (view.getMeasuredWidth()),
(int) (view.getMeasuredHeight()), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(overlay);
canvas.translate(-view.getLeft(), -view.getTop());
canvas.drawBitmap(mBitmap, 100, 0,null);
canvas.drawBitmap(mBitmap, -100, 0,null);
RenderScript rs = RenderScript.create(getApplicationContext());
Allocation overlayAlloc = Allocation.createFromBitmap(
rs, overlay);
ScriptIntrinsicBlur blur = ScriptIntrinsicBlur.create(
rs, overlayAlloc.getElement());
blur.setInput(overlayAlloc);
blur.setRadius(radius);
blur.forEach(overlayAlloc);
overlayAlloc.copyTo(overlay);
view.setBackground(new BitmapDrawable(
getResources(), overlay));
rs.destroy();
}//end blur
The key to blurring out both sides of the ImageView instead of just the left side
changing the 2nd parameter in the canvas.drawBitmap to a negative value
eg 100 becomes -100
so after canvas.drawBitmap(mBitmap, 100, 0,null); you add canvas.drawBitmap(mBitmap, -100, 0,null);
Hope this helps.
I want to take screenshot of rendered remotevideo view.
So far I tried these functions:
1.
public Bitmap getLastFrame(RelativeLayout remoteView)
{
Bitmap bitmap = null;
if(remoteView.getChildCount()>0) {
SurfaceViewRenderer rtcEAGLView = (SurfaceViewRenderer) remoteView.getChildAt(0);
rtcEAGLView.getBackground();
bitmap = ActivityUtils.takeScreenshot(rtcEAGLView);
}
return bitmap;
}
public static Bitmap takeScreenshot(View container) {
container.setVisibility(View.VISIBLE);
getScreenShot(container);
final Bitmap bmp = Bitmap.createBitmap(container.getWidth(), container.getHeight(), Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(bmp);
container.setDrawingCacheEnabled(true);
container.measure(
View.MeasureSpec.makeMeasureSpec(canvas.getWidth(), View.MeasureSpec.EXACTLY),
View.MeasureSpec.makeMeasureSpec(canvas.getHeight(), View.MeasureSpec.EXACTLY));
container.layout(0, 0, container.getMeasuredWidth(), container.getMeasuredHeight());
canvas.drawBitmap(container.getDrawingCache(), 0, 0, new Paint());
return bmp;
}
void frame()
{
EGL10 egl = (EGL10) EGLContext.getEGL();
GL10 gl = (GL10)egl.eglGetCurrentContext().getGL();
Bitmap snapshotBitmap = createBitmapFromGLSurface(0, 0, 400, 400/* height*/, gl);
}
By trying these method I am not able to get screenshot as bitmap returns blank space only. rest of the area screenshot get captured but rendered part is not deplayed in that.
The reason that I'm using Picasso is because I need a rounded image and I could achieve this with Picasso using Transformation:
public class CircleTransform implements Transformation {
#Override
public Bitmap transform(Bitmap source) {
int size = Math.min(source.getWidth(), source.getHeight());
int x = (source.getWidth() - size) / 2;
int y = (source.getHeight() - size) / 2;
Bitmap squaredBitmap = Bitmap.createBitmap(source, x, y, size, size);
if (squaredBitmap != source) {
source.recycle();
}
Bitmap bitmap = Bitmap.createBitmap(size, size, source.getConfig());
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint();
BitmapShader shader = new BitmapShader(squaredBitmap,
BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP);
paint.setShader(shader);
paint.setAntiAlias(true);
float r = size / 2f;
canvas.drawCircle(r, r, r, paint);
squaredBitmap.recycle();
return bitmap;
}
#Override
public String key() {
return "circle";
}
}
And then :
Picasso.with(this).load(R.drawable.image)
.transform(new CircleTransform()).into(photo);
But I'm taking a Bitmap from a Camera and I need to put the image inside of ImageView, rounded! I was trying to use Bitmap to File but it doesnt' work!
I`m tring to to load an image from an URL into a Bitmap using the Picasso library , but most of the examples i found refer to loading a Bitmap to a ImageView or something similar.
The code should be something like this , according to the documentation.
public void loadImage() {
Picasso.with(getBaseContext()).load("image url").into(new Target() {
#Override
public void onPrepareLoad(Drawable arg0) {
}
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom arg1) {
Bitmap bitImage = Bitmap(getApplicationContext(),bitmap);
}
#Override
public void onBitmapFailed(Drawable arg0) {
}
});
}
But Bitmap bitImage = Bitmap(getApplicationContext(),bitmap); doesn't seem to be correct, since i`m getting a Method call expected error.
It looks like you are not creating the Bitmap properly, but if I was in your position I would create a scaled bitmap like so:
public Bitmap getResizedBitmap(Bitmap bm, int newWidth, int newHeight) {
int width = bm.getWidth();
int height = bm.getHeight();
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// CREATE A MATRIX FOR THE MANIPULATION
Matrix matrix = new Matrix();
// RESIZE THE BIT MAP
matrix.postScale(scaleWidth, scaleHeight);
// "RECREATE" THE NEW BITMAP
Bitmap resizedBitmap = Bitmap.createBitmap(
bm, 0, 0, width, height, matrix, false);
bm.recycle();
return resizedBitmap;
}
Then set it to an imageView like so:
mImg.setImageBitmap(img);
Overall it would look like this:
public void loadImage() {
Picasso.with(getBaseContext()).load("image url").into(new Target() {
// ....
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom arg1) {
// Pick arbitrary values for width and height
Bitmap resizedBitmap = getResizedBitmap(bitmap, newWidth, newHeight);
mImageView.setBitmap(resizedBitmap);
}
// ....
});
}
}
public Bitmap getResizedBitmap(Bitmap bm, int newWidth, int newHeight) {
int width = bm.getWidth();
int height = bm.getHeight();
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// CREATE A MATRIX FOR THE MANIPULATION
Matrix matrix = new Matrix();
// RESIZE THE BIT MAP
matrix.postScale(scaleWidth, scaleHeight);
// "RECREATE" THE NEW BITMAP
Bitmap resizedBitmap = Bitmap.createBitmap(
bm, 0, 0, width, height, matrix, false);
bm.recycle();
return resizedBitmap;
}
But I question you using Target altogether, usually that is for a very specialized case. You should be calling the singleton of Picasso in the same class you will be displaying images. Usually this is in an Adapter (RecyclerView Adapter maybe) like so:
Picasso.with(mContext)
.load("image url")
.into(mImageView);