Out of memory during working with Bitmap in android - android

I use the method quoted below to round the corners of any bitmap. Some time it works perfectly, some time not because of OutOfMemory exception. The exception often occur at the line
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Config.ARGB_8888);
Do I miss any special codes here? Please help me.
public static Bitmap roundBitmap(Bitmap bitmap, int roundedRadius) {
if (bitmap == null)
return null;
if (roundedRadius == 0) {
return bitmap;
}
// Bitmap output = bitmap.copy(Config.ARGB_8888, true);
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xffffff00;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
final RectF rectF = new RectF(rect);
final float roundPx = roundedRadius;
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}

If you don't need the original bitmap after calling roundBitmap() you should call bitmap.recycle() to free the memory used by bitmap.

Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), new BitmapFactory.Options().inSampleSize=4);
Try above code to create bitmap.

Related

Using android crop-library

I wanna use android crop library(https://github.com/biokys/cropimage) with custom settings.
Making an example circle line that doesn't show on the cropped image is my goal.
First of all get the cropped image
Bitmap newbitmap = thecropedBitmap;
And once you get the newbitmap you can easily crop again but this time you are going to get the circle using the following method:
public Bitmap getCroppedBitmap(Bitmap bitmap) {
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
// canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
canvas.drawCircle(bitmap.getWidth() / 2, bitmap.getHeight() / 2,
bitmap.getWidth() / 2, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
//Bitmap _bmp = Bitmap.createScaledBitmap(output, 60, 60, false);
//return _bmp;
return output;
}
Add this line:
newbitmap = getCroppedBitmap(newbitmap);

how to create a circular image in android... as google+ is using

I am trying to create a circular image, by putting a circular transparent image over it...
But I want to create the circular image as in Google+, is there any other way, without using canvas?
Bitmap circleBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
BitmapShader shader = new BitmapShader (bitmap, TileMode.CLAMP, TileMode.CLAMP);
Paint paint = new Paint();
paint.setShader(shader);
paint.setAntiAlias(true);
paint.setFilterBitmap(true);
paint.setDither(true);
paint.setColor(Color.parseColor("#BAB399"));
Canvas c = new Canvas(circleBitmap);
c.drawCircle(bitmap.getWidth()/2, bitmap.getHeight()/2, bitmap.getWidth()/2, paint);
img.setImageBitmap(circleBitmap);
public Bitmap getCroppedBitmap(Bitmap bitmap) {
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawCircle(bitmap.getWidth() / 2, bitmap.getHeight() / 2,
bitmap.getWidth() / 2, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}
or use a mask that have into the center a transparent circle
In android.support.v4 a new class is introduced for creating circular image or rounded cornered image.
Which is RoundedBitmapDrawablethere's no need to use customized methods.To set any image as round cornered or circular follow the below syntax.
RoundedBitmapDrawable roundedBitmapDrawable = RoundedBitmapDrawableFactory.create(mContext.getResources(), bitmap);
roundedBitmapDrawable.setCornerRadius(pixels);
imageView.setImageDrawable(roundedBitmapDrawable);
It's that simple. Source

Drawing a canvas into a bitmap

I want to save the canvas in a bitmap so I could draw that bitmap on other canvas.
the problem is that i dont know how to set the bitmap size to be the whole canvas(not the whole screen, the size of a layout of mine)
how do i set the bitmap size? and then how do i save my canvas on it?
Thanks for the help :D
I use this procedure and you can set the width and height of your view instead of bitmap.getWidth() and bitmap.getHeight() as here I am overriding a bitmap
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
final RectF rectF = new RectF(rect);
final float roundPx = pixels;
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
Hope this helps :)

Border over a bitmap with rounded corners in Android

I used the below to make a bitmap with rounded corners. Now I want to draw a line around the bitmap.
private BitmapDrawable roundCornered(BitmapDrawable scaledBitmap, int i) {
Bitmap bitmap = scaledBitmap.getBitmap();
result = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(),
Bitmap.Config.ARGB_8888);
canvas = new Canvas(result);
color = 0xff424242;
paint = new Paint();
rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
rectF = new RectF(rect);
roundPx = i;
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(Color.BLUE);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
BitmapDrawable finalresult = new BitmapDrawable(result);
return finalresult;
}
I got the image below, but my actual need is that I must draw a border around the image.
I put the following together for myself.
public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, int color, int cornerDips, int borderDips, Context context) {
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(),
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int borderSizePx = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, (float) borderDips,
context.getResources().getDisplayMetrics());
final int cornerSizePx = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, (float) cornerDips,
context.getResources().getDisplayMetrics());
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
final RectF rectF = new RectF(rect);
// prepare canvas for transfer
paint.setAntiAlias(true);
paint.setColor(0xFFFFFFFF);
paint.setStyle(Paint.Style.FILL);
canvas.drawARGB(0, 0, 0, 0);
canvas.drawRoundRect(rectF, cornerSizePx, cornerSizePx, paint);
// draw bitmap
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
// draw border
paint.setColor(color);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth((float) borderSizePx);
canvas.drawRoundRect(rectF, cornerSizePx, cornerSizePx, paint);
return output;
}
Credits, of course, to http://ruibm.com/?p=184
How about to prepare 9-patch image like below and set it as a background by using android:background
I use BitmapShader and drawRoundRect do it and it work for me, look at the screenshot
RectF roundRect; // the Rect you have to draw into
Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
// draw the border at bottom
mPaint.setStyle(Paint.Style.FILL);
mPaint.setColor(mBorderColor);
canvas.drawRoundRect(roundRect, mRadius, mRadius, mPaint);
// ------------------ draw scheme bitmap
roundRect.set(itemRect.left + mBorderSize, itemRect.top + mBorderSize, itemRect.right - mBorderSize, itemRect.bottom - mBorderSize);
Shader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
mPaint.setShader(shader);
canvas.drawRoundRect(roundRect, mRadius, mRadius, mPaint);
mPaint.setShader(null);
I did many search to implement that effect by code, before I found another way but it's not perfect enough, you can see the jaggy on each corner, I set Paint.setAntiAlias(true), Paint.setDither(true), Paint.setFilterBitmap(true), but It doesn't work, so I hope somebody can help me.
RectF roundRect = new RectF(itemRect);
Bitmap bitmap = scheme.getSchemeBitmap(getResources());
mPaint.setStyle(Paint.Style.FILL);
mPaint.setColor(mSchemeSelectedColor);
canvas.drawRoundRect(roundRect, mSchemeCornerRadius, mSchemeCornerRadius, mPaint);
roundRect.set(itemRect.left + mBorderSize, itemRect.top + mBorderSize, itemRect.right - mBorderSize, itemRect.bottom - mBorderSize);
Path clipPath = new Path();
clipPath.addRoundRect(roundRect, mSchemeCornerRadius, mSchemeCornerRadius, Path.Direction.CW);
canvas.save(Canvas.CLIP_SAVE_FLAG);
canvas.clipPath(clipPath);
canvas.drawBitmap(bitmap, null, roundRect, mPaint);
canvas.restore();
Unfortunately there's no nice and neat "border" parameter in Android, but the simplest way to do it is to encase that within another layout, set the background of the parent layout to your border color/drawable and then set a padding on it. The padding will appear around your BitmapDrawable.
my way:
public static Bitmap getRoundedCornerBitmap1(Bitmap bitmap, int color, int cornerDips, int borderDips) {
Bitmap output = Bitmap.createBitmap(bitmap.getWidth()+2*borderDips,
bitmap.getHeight()+2*borderDips,
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
canvas.drawColor(Color.TRANSPARENT);
final RectF rectF = new RectF(0, 0, output.getWidth(), output.getHeight());
final Paint paint = new Paint();
// prepare canvas for transfer
paint.setAntiAlias(true);
paint.setStrokeWidth((float) borderDips);
paint.setColor(Color.WHITE);
paint.setStyle(Paint.Style.FILL);
canvas.drawRoundRect(rectF, borderDips, borderDips, paint);
canvas.drawBitmap(bitmap, borderDips, borderDips, null);
bitmap.recycle();
return output;
}
Result

Changing Image as Rounded Corner

I've one listview with some items. In my listview i've using custom adapter for displaying the items with images. My images in items are coming from JSON My images are like this -
Now, I just need the image with rounded corner. How do i achieve this?
public static Bitmap getRoundedCornerBitmap(Bitmap bitmap) {
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
final RectF rectF = new RectF(rect);
final float roundPx = 12;
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}
code extracted from http://ruibm.com/?p=184
Bitmap myCoolBitmap = ... ; // <-- Your bitmap you want rounded
int w = myCoolBitmap.getWidth(), h = myCoolBitmap.getHeight();
We have to make sure our rounded corners have an alpha channel in most cases
Bitmap rounder = Bitmap.createBitmap(w,h,Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(rounder);
We're going to apply this paint eventually using a porter-duff xfer mode.
This will allow us to only overwrite certain pixels. RED is arbitrary. This could be any color that was fully opaque (alpha = 255)
Paint xferPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
xferPaint.setColor(Color.RED);
We're just reusing xferPaint to paint a normal looking rounded box, the 20.f is the amount we're rounding by.
canvas.drawRoundRect(new RectF(0,0,w,h), 20.0f, 20.0f, xferPaint);
Now we apply the 'magic sauce' to the paint
xferPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
Now apply this bitmap ontop of your image:
canvas.drawBitmap(myCoolBitmap, 0,0, null);
canvas.drawBitmap(rounder, 0, 0, xferPaint);
public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, int pixels) {
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap
.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
final RectF rectF = new RectF(rect);
final float roundPx = pixels;
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}
Check out this previous thread, brilliant answer on how to get rounded edges for bitmap images.

Categories

Resources