Android canvas add stroke and elevation - java

I am creating a thumbnail from a large image via canvas to use it as marker in google map and how can i add a border (stroke) of 2 dp and also light elevation in my thumbnail
Canvas function
public static Bitmap getCroppedBitmap(Bitmap bitmap) {
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Bitmap.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(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}

Related

Android: Cropping an Image from the Bottom Up

I have an image, and I am trying to overlay a cropped version of the image over the original. Something like this:
Original
Overlay Image
Image after the overlay image is cropped to roughly 50%
Right now, my code below reverses what I want, and returns an image like this:
public void setOverlay(ImageView image, Bitmap originalBitmap, double percentageCompleted) {
int percentHeight;
int height = originalBitmap.getHeight();
Bitmap cropped;
if(percentageCompleted == 0){
cropped = Bitmap.createBitmap(overlay, 0, 0, overlay.getWidth() , 0 );
} else {
percentHeight = (int) Math.floor(height * (percentageCompleted));
Log.d("HEIGHT", Double.toString(height));
Log.d("PERCENT Completed", Double.toString(percentageCompleted));
Log.d("PERCENT HEIGHT", Integer.toString(percentHeight));
cropped = Bitmap.createBitmap(overlay, 0, 0, overlay.getWidth() , height-percentHeight);
}
originalBitmap = overlay(originalBitmap, cropped);
//set imageview to new bitmap
image.setImageBitmap(originalBitmap );
}
public Bitmap overlay(Bitmap bmp1, Bitmap bmp2) {
Bitmap bmp3 = bmp1.copy(Bitmap.Config.ARGB_8888,true);//mutable copy
Canvas canvas = new Canvas(bmp3 );
canvas.drawBitmap(bmp2, new Matrix(), null);
return bmp3;
}
I know I could reverse the image files, but I want to start with the original image and have the overlay draw upwards, rather than starting with the overlay, and drawing the original downwards. Any help is appreciated!
You can use this method:
Canvas.drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint)
Here is my overlay method that may meet your need:
public static Bitmap overlay(Bitmap base, Bitmap overlay, Float percentage) {
Bitmap resultBitmap = Bitmap.createBitmap(base.getWidth(), base.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(resultBitmap);
Paint paint = new Paint();
// base bitmap
canvas.drawBitmap(base, 0F, 0F, paint);
// overlay bitmap
int yOffset = (int) (percentage * base.getHeight());
Rect rect = new Rect(0, yOffset, overlay.getWidth(), overlay.getHeight());
canvas.drawBitmap(overlay, rect, rect, paint);
return resultBitmap;
}

How to set dynamically gradient tint to imageView on Android

In my application I want to set dynamically gradient colors to imageView.
I can set solid color with the following code:
imageView.setColorFilter(ContextCompat.getColor(context, R.color.grayColor),
android.graphics.PorterDuff.Mode.MULTIPLY);
But I want to set gradient color instead of solid color.
How can I do it?
You can use this method after getting bitmap
public Bitmap setGradientBackground(Bitmap originalBitmap) {
int width = originalBitmap.getWidth();
int height = originalBitmap.getHeight();
Bitmap updatedBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(updatedBitmap);
canvas.drawBitmap(originalBitmap, 0, 0, null);
Paint paint = new Paint();
LinearGradient shader = new LinearGradient(0, 0, 0, height, 0xFFF0D252, 0xFFF07305, Shader.TileMode.CLAMP);
paint.setShader(shader);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawRect(0, 0, width, height, paint);
return updatedBitmap;
}

Draw a small bitmap above a larger bitmap

I am trying to draw something like this, but it is not displaying bitmap 2. Only bitmap 1 (the larger one) displays.
//bitmap1 and bitmap2 already initialized
Bitmap resultBitmap = Bitmap.createBitmap(cubemap.getWidth(), cubemap.getHeight(), cubemap.getConfig());
Canvas canvas = new Canvas(resultBitmap);
canvas.drawBitmap(bitmap1, new Matrix(), null);
canvas.drawBitmap(bitmap2, (bitmap1.getWidth() - bitmap2.getWidth()) / 3, (bitmap1.getHeight()) , new Paint());
return resultBitmap;
set image in Imageview
imageView1 = (ImageView) findViewById(R.id.imageView1);
imageView1.setImageBitmap(drawUsingBitmap());
Using Bitmap
public Bitmap drawUsingBitmap() {
bitmapLarge = BitmapFactory.decodeResource(getResources(), R.drawable.bitmap_large);
bitmapSmall = BitmapFactory.decodeResource(getResources(), R.drawable.bitmap_small);
Bitmap resultBitmap = Bitmap.createBitmap(bitmapLarge.getWidth(), bitmapSmall.getHeight() + bitmapLarge.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(resultBitmap);
// using bitmap
Paint paint = new Paint();
paint.setColor(Color.BLACK);
canvas.drawBitmap(bitmapSmall, bitmapSmall.getWidth() / 2, 0, paint);
canvas.drawBitmap(bitmapLarge, 0, bitmapSmall.getHeight() - 10, paint);
return resultBitmap;
}
Using drawRect
public Bitmap draWUsingRect() {
// using rectangle
int widthSmall = 120;
int heightSmall = 80;
int widthLarge = 400;
int heightLarge = 300;
Bitmap resultBitmap = Bitmap.createBitmap(widthLarge + 20, heightSmall + heightLarge + 20, Config.ARGB_8888);
Canvas canvas = new Canvas(resultBitmap);
Paint paint = new Paint();
paint.setColor(Color.BLACK);
paint.setStyle(Style.STROKE);
paint.setStrokeWidth(5);
canvas.drawRect(new Rect(widthSmall / 2, 0, widthSmall, heightSmall), paint);
canvas.drawRect(new Rect(0, heightSmall, widthLarge, heightSmall + heightLarge), paint);
return resultBitmap;
}
I hope it is helpful to you.

android-How to border canvas

I'm making a circle canvas and I want to add a border to it .
final int color = 0xffa19774;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, sbmp.getWidth(), sbmp.getHeight());
paint.setAntiAlias(true);
paint.setFilterBitmap(true);
paint.setDither(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(Color.parseColor("#BAB399"));
canvas.drawCircle(sbmp.getWidth() / 2+0.7f, sbmp.getHeight() / 2+0.7f,
sbmp.getWidth() / 2+0.1f, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(sbmp, rect, rect, paint);
How can I add a border around this canvas ?
You can draw a border using Paint.STYLE.STROKE. You need to do two separate calls to drawCircle():
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.parseColor("#BAB399")); // set fill color
canvas.drawCircle(sbmp.getWidth() / 2+0.7f, sbmp.getHeight() / 2+0.7f,
sbmp.getWidth() / 2+0.1f, paint);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(10); // set stroke width
paint.setColor(Color.parseColor("#ffffff")); // set stroke color
canvas.drawCircle(sbmp.getWidth() / 2+0.7f, sbmp.getHeight() / 2+0.7f,
sbmp.getWidth() / 2+0.1f, paint);
To draw a border around a circle, you only need to draw two circles on to your canvas. Both circles have the same dimension however the circle below should have a stroke.
Also, to draw an image border, the circle below should be given a bigger radius than the one above.
public static Bitmap getRoundedCroppedBitmap(Bitmap bitmap, int radius) {
Bitmap finalBitmap;
if (bitmap.getWidth() != radius || bitmap.getHeight() != radius)
finalBitmap = Bitmap.createScaledBitmap(bitmap, radius, radius,
false);
else
finalBitmap = bitmap;
Bitmap output = Bitmap.createBitmap(finalBitmap.getWidth(),
finalBitmap.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, finalBitmap.getWidth(),
finalBitmap.getHeight());
paint.setAntiAlias(true);
paint.setFilterBitmap(true);
paint.setDither(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(Color.parseColor("#BAB399"));
canvas.drawCircle(finalBitmap.getWidth() / 2 + 0.7f, finalBitmap.getHeight() / 2 + 0.7f, finalBitmap.getWidth() / 2 + 0.1f, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(finalBitmap, rect, rect, paint);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(20); // set stroke width
paint.setColor(Color.parseColor("#00ff00")); // set stroke color
canvas.drawCircle(finalBitmap.getWidth() / 2 + 0.7f, finalBitmap.getHeight() / 2 + 0.7f, finalBitmap.getWidth() / 2 + 0.1f, paint);
return output;
}
The example above returns a bitmap circle image with a border.
This is the code to draw the stroke
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(20); // set stroke width
paint.setColor(Color.parseColor("#00ff00")); // set stroke color
canvas.drawCircle(finalBitmap.getWidth() / 2 + 0.7f, finalBitmap.getHeight() / 2 + 0.7f, finalBitmap.getWidth() / 2 + 0.1f, paint);

Adding a round frame circle on rounded bitmap

Im trying to create a round frame around my bitmap!
With this code im able to make my bitmap round:
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 = 0xff4242DB;
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 = bitmap.getWidth()/2;
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.drawCircle(0, 0, bitmap.getWidth(), paint);
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}
What i've tried is to draw a circle(the outcommented line) with canvas, but It had no result.
Does anyone know how I can add a circular border around it?
EDIT
When I use the line:
canvas.drawCircle(0, 0, bitmap.getWidth(), paint);
The effect is, that 3 corners get rounded but the upper left stays the same(90 degrees)
But I can't see any line or circle!
Update
There now is RoundedBitmapDrawable and a corresponding factory in the Support library I recommend to use that, unless more flexibility is required.
Original Answer
You have to draw the circle after the bitmap. This is what did the trick for me.
int w = bitmap.getWidth();
int h = bitmap.getHeight();
int radius = Math.min(h / 2, w / 2);
Bitmap output = Bitmap.createBitmap(w + 8, h + 8, Config.ARGB_8888);
Paint p = new Paint();
p.setAntiAlias(true);
Canvas c = new Canvas(output);
c.drawARGB(0, 0, 0, 0);
p.setStyle(Style.FILL);
c.drawCircle((w / 2) + 4, (h / 2) + 4, radius, p);
p.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
c.drawBitmap(bitmap, 4, 4, p);
p.setXfermode(null);
p.setStyle(Style.STROKE);
p.setColor(Color.WHITE);
p.setStrokeWidth(3);
c.drawCircle((w / 2) + 4, (h / 2) + 4, radius, p);
return output;
This does of course not include the fancy shadow of your example.
You might want to play around a little bit with the additional pixels.

Categories

Resources