How to draw a stroke in a Bitmap using canvas? - android

I need to round the corners of a Bitmap. After that, I need to add a border for it. I have done the source below to round the corners but I don't know how to draw a border in the Bitmap using Canvas. Is there any way to do it? Thanks
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(),
Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
final RectF rectF = new RectF(rect);
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
canvas.drawRoundRect(rectF, 20.0f, 20.0f, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
I have added the solution:
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(),
Config.ARGB_8888);
Canvas canvas = new Canvas(output);
Paint paint = new Paint();
Paint paintStroke = new Paint();
paintStroke.setStrokeWidth(2);
paintStroke.setStyle(Paint.Style.STROKE);
paintStroke.setColor(Color.RED);
paintStroke.setAntiAlias(true);
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
final RectF rectF = new RectF(rect);
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
canvas.drawRoundRect(rectF, 20.0f, 20.0f, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
canvas.drawRoundRect(rectF, round, round, paintStroke);
return output;

try this Method and pass bitmap it will return bitmap with border with angle :
Bitmap rotateAndFrame(Bitmap bitmap,float angle) {
// final boolean positive = sRandom.nextFloat() >= 0.5f;
// final float angle = (ROTATION_ANGLE_MIN + sRandom.nextFloat() *
// ROTATION_ANGLE_EXTRA) * (positive ? 1.0f : -1.0f);
final double radAngle = Math.toRadians(angle);
final int bitmapWidth = bitmap.getWidth();
final int bitmapHeight = bitmap.getHeight();
final double cosAngle = Math.abs(Math.cos(radAngle));
final double sinAngle = Math.abs(Math.sin(radAngle));
final int strokedWidth = (int) (bitmapWidth + 2 * PHOTO_BORDER_WIDTH);
final int strokedHeight = (int) (bitmapHeight + 2 * PHOTO_BORDER_WIDTH);
final int width = (int) (strokedHeight * sinAngle + strokedWidth * cosAngle);
final int height = (int) (strokedWidth * sinAngle + strokedHeight * cosAngle);
final float x = (width - bitmapWidth) / 2.0f;
final float y = (height - bitmapHeight) / 2.0f;
final Bitmap decored = Bitmap.createBitmap(width, height,
Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(decored);
canvas.rotate(angle, width / 2.0f, height / 2.0f);
canvas.drawBitmap(bitmap, x, y, sPaint);
canvas.drawRect(x, y, x + bitmapWidth, y + bitmapHeight, sStrokePaint);
canvas.drawText(String.valueOf(k_value),(one_piecewidth*0.84f),
(one_pieceheight*0.35f),sNumPaint);
k++;
return decored;
}
hope it helps...
edited:
private static final float PHOTO_BORDER_WIDTH2 = 3.0f;
private static final float PHOTO_BORDER_WIDTH = 1.0f;
private static final int PHOTO_BORDER_COLOR2=0x00000000;
private static final int PHOTO_BORDER_COLOR = 0xffffffff;
private static final Paint sPaint =
new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
private static final Paint sStrokePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private static final Paint sNumPaint = new Paint(Paint.LINEAR_TEXT_FLAG);
static {
sNumPaint.setColor(Color.BLACK);
sNumPaint.setTextSize(25);
sNumPaint.setTextAlign(Align.RIGHT);
}
static {
sStrokePaint.setStrokeWidth(PHOTO_BORDER_WIDTH);
sStrokePaint.setStyle(Paint.Style.STROKE);
// sStrokePaint.measureText("hello");
sStrokePaint.setColor(PHOTO_BORDER_COLOR);
}

Related

Android picasso image's edge is cut after transform

I am using Picasso to transform an image into a rounded square image.
It also has the border. But when I put this image to Imageview, it's edge is cut. Any solution for this? Android version is 4.4.2.
My Imageview looks like this.
<ImageView
android:id="#+id/imageview_picture"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/edge_margin"
android:layout_marginRight="#dimen/edge_margin"
android:adjustViewBounds="true" />
Below is code.
#Override public Bitmap transform(Bitmap source) {
int ratio = source.getWidth() / mDisplayWidth;
float strokeWidth = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, Constants.SHAPE_STROKE_WIDTH, mDisplayMetrics) * ratio;
float radius = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, Constants.SQUARE_RADIUS, mDisplayMetrics) * ratio;
int x = (int) (mRectF.left * ratio);
int y = (int) (mRectF.top * ratio);
int width = (int) ((mRectF.right - mRectF.left) * ratio);
int height = (int) ((mRectF.bottom - mRectF.top) * ratio);
Bitmap bitmap = Bitmap.createBitmap(source, x, y, width, height);
source.recycle();
return getRoundedCornerBitmap(bitmap, radius, strokeWidth);
}
#Override public String key() {
return "card_square";
}
private Bitmap getRoundedCornerBitmap(Bitmap bitmap, int color, float cornerSizePx, float borderSizePx) {
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(),
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
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);
bitmap.recycle();
// draw border
paint.setColor(color);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(borderSizePx);
canvas.drawRoundRect(rectF, cornerSizePx, cornerSizePx, paint);
return output;
}`
This is what I used in one of my previous project to transform an image into a rounded image:
public Bitmap getRoundedBitmap(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;
}

How to get particular cropping image using canvas circular image?

I am create a custom ImageView with Pinch IN-OUT zoom and circular crop image.The Pinch in-out is wroking fine but when i trying to cropping image, can't get the particulr circle image. I'm using Pinch in-out working based on onTuchListener and Circular Cropping based on canvas class.
I have used below mentioned code for Pinch in-out and Circle Crop image:
#Override
protected void onDraw(Canvas canvas) {
onDrawReady = true;
imageRenderedAtLeastOnce = true;
if (delayedZoomVariables != null) {
setZoom(delayedZoomVariables.scale, delayedZoomVariables.focusX, delayedZoomVariables.focusY, delayedZoomVariables.scaleType);
delayedZoomVariables = null;
}
super.onDraw(canvas);
if (bitmap == null) {
circleWindowFrame(); //Creating circle view
}
canvas.drawBitmap(bitmap, 0, 0, null);
}
protected void circleWindowFrame() {
bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
Canvas osCanvas = new Canvas(bitmap);
RectF outerRectangle = new RectF(0, 0, bitmap.getWidth(), bitmap.getHeight());
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(getResources().getColor(R.color.overlay));
paint.setAlpha(99);
osCanvas.drawRect(outerRectangle, paint);
paint.setColor(Color.TRANSPARENT);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT));
float centerX = getWidth() / 2;
float centerY = getHeight() / 2;
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
int width = metrics.widthPixels;
float radius = width / 2;
osCanvas.drawCircle(centerX, centerY, radius, paint);
}
This code for Cropping:
public static Bitmap getCrop() {
Bitmap circleBitmap;
circleBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
BitmapShader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
Paint paint = new Paint();
paint.setShader(shader);
paint.setAntiAlias(true);
Canvas c = new Canvas(circleBitmap);
c.drawCircle(bitmap.getWidth() / 2, bitmap.getHeight() / 2, bitmap.getWidth() / 2, paint);
return bitmap;
}
Thanks for Advance...
try this
public static Bitmap toOvalBitmap(#NonNull Bitmap bitmap) {
int width = bitmap.getWidth();
int height = bitmap.getHeight();
Bitmap output = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
int color = 0xff424242;
Paint paint = new Paint();
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
RectF rect = new RectF(0, 0, width, height);
canvas.drawOval(rect, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(bitmap, 0, 0, paint);
bitmap.recycle();
return output;
}

Add a drawable within a specified "Path" variable in android?

I am drawing a hexagonal path in android app. Now I want to place an image in the drawn path. Below is the code I am using to draw the path.
combPath = getHexPath(cellWidth / 2f, cellWidth / 2f, (float) (cellWidth * Math.sqrt(3) / 4));
fillPaint.setColor(cellSet[c][r] ? Color.RED : Color.WHITE);
canvas.drawPath(combPath, fillPaint);
Method getHexPath()
private Path getHexPath(float size, float centerX, float centerY) {
Path path = new Path();
for (int j = 0; j <= 6; j++) {
double angle = j * Math.PI / 3;
float x = (float) (centerX + size * Math.cos(angle));
float y = (float) (centerY + size * Math.sin(angle));
if (j == 0) {
path.moveTo(x, y);
} else {
path.lineTo(x, y);
}
}
return path;
}
Now I have to place an image in the hexagonal path using "path()" variable. How can I achieve it?
TIA
Try to use something like this:
Bitmap bitmap = getBitmap(); // retrieve bitmap that you want to draw somehow
Paint paint = new Paint();
paint.setAntiAlias(true);
combPath = getHexPath(cellWidth / 2f, cellWidth / 2f, (float) (cellWidth * Math.sqrt(3) / 4));
canvas.drawPath(combPath, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, 0, 0, paint);
UPDATED
Here is an example function of how you can do that
private Bitmap getCroppedBitmap(Bitmap original) {
Bitmap output = Bitmap.createBitmap(original.getWidth(),
original.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, original.getWidth(), original.getHeight());
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
Path path = new Path();
path.moveTo(30, 20);
path.lineTo(120, 30);
path.lineTo(110, 120);
path.lineTo(20, 110);
path.lineTo(30, 20);
// canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
canvas.drawPath(path, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(original, rect, rect, paint);
return output;
}
You just need to place your bitmap, play with width/height and also insert your path. This code worked for me.

Shadow effect for image in all sides

I need to create shadow effect for an image .
private static Bitmap getDropShadow3(Bitmap bitmap) {
if (bitmap==null) return null;
int think = 6;
int w = bitmap.getWidth();
int h = bitmap.getHeight();
int newW = w - (think);
int newH = h - (think);
Bitmap.Config conf = Bitmap.Config.ARGB_8888;
Bitmap bmp = Bitmap.createBitmap(w, h, conf);
Bitmap sbmp = Bitmap.createScaledBitmap(bitmap, newW, newH, false);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
Canvas c = new Canvas(bmp);
// Right
Shader rshader = new LinearGradient(newW, 0, w, 0, Color.GRAY, Color.LTGRAY, Shader.TileMode.CLAMP);
paint.setShader(rshader);
c.drawRect(newW, think, w, newH, paint);
// Bottom
Shader bshader = new LinearGradient(0, newH, 0, h, Color.GRAY, Color.LTGRAY, Shader.TileMode.CLAMP);
paint.setShader(bshader);
c.drawRect(think, newH, newW , h, paint);
//Corner
Shader cchader = new LinearGradient(0, newH, 0, h, Color.LTGRAY, Color.LTGRAY, Shader.TileMode.CLAMP);
paint.setShader(cchader);
c.drawRect(newW, newH, w , h, paint);
c.drawBitmap(sbmp, 0, 0, null);
return bmp;
}
i used the above code, and i get two sides (Right, bottom) shadow effect . How can i make the effect in all sides including (top,Left)?
the method that you are using; may cause some problems with a certain type of images (irregular ones)
try this method instead (much much easier to understand and more flexible):
public Bitmap addShadowToBitmap(final Bitmap bm, final int dstHeight, final int dstWidth, int color, int size, float dx, float dy) {
final Bitmap mask = Bitmap.createBitmap(dstWidth, dstHeight, Config.ALPHA_8);
final Matrix scaleToFit = new Matrix();
final RectF src = new RectF(0, 0, bm.getWidth(), bm.getHeight());
final RectF dst = new RectF(0, 0, dstWidth - dx, dstHeight - dy);
scaleToFit.setRectToRect(src, dst, ScaleToFit.CENTER);
final Matrix dropShadow = new Matrix(scaleToFit);
dropShadow.postTranslate(dx, dy);
final Canvas maskCanvas = new Canvas(mask);
final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
maskCanvas.drawBitmap(bm, scaleToFit, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_OUT));
maskCanvas.drawBitmap(bm, dropShadow, paint);
final BlurMaskFilter filter = new BlurMaskFilter(size, Blur.NORMAL);
paint.reset();
paint.setAntiAlias(true);
paint.setColor(color);
paint.setMaskFilter(filter);
paint.setFilterBitmap(true);
final Bitmap ret = Bitmap.createBitmap(dstWidth, dstHeight, Config.ARGB_8888);
final Canvas retCanvas = new Canvas(ret);
retCanvas.drawBitmap(mask, 0, 0, paint);
retCanvas.drawBitmap(bm, scaleToFit, null);
mask.recycle();
return ret;
}
call it through:
addShadowToBitmap(arg0, arg1, arg2, arg3, arg4, arg5, arg6);
and it will return you a bitmap.
hope this will help.
Ahmad's code was not quite right for me. I augmented his code to determine w/h of returned bitmap based on the dx/dy and shadow size. This code worked for me with a bitmap that was a signature of a user.
public Bitmap addShadowToBitmap(final Bitmap bm, int color, int size, int dx, int dy) {
int dstWidth = bm.getWidth() + dx + size/2;
int dstHeight = bm.getHeight() + dy + size/2;
final Bitmap mask = Bitmap.createBitmap(dstWidth, dstHeight, Bitmap.Config.ALPHA_8);
final Canvas maskCanvas = new Canvas(mask);
final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
maskCanvas.drawBitmap(bm, 0, 0, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT));
maskCanvas.drawBitmap(bm, dx, dy, paint);
final BlurMaskFilter filter = new BlurMaskFilter(size, BlurMaskFilter.Blur.NORMAL);
paint.reset();
paint.setAntiAlias(true);
paint.setColor(color);
paint.setMaskFilter(filter);
paint.setFilterBitmap(true);
final Bitmap ret = Bitmap.createBitmap(dstWidth, dstHeight, Bitmap.Config.ARGB_8888);
final Canvas retCanvas = new Canvas(ret);
retCanvas.drawBitmap(mask, 0, 0, paint);
retCanvas.drawBitmap(bm, 0, 0, null);
mask.recycle();
return ret;
}

How to cut a rectangular drawable in semi circle shape ?

I need help with cutting a rectangular drawable in a semi circular shape.
I tried using Path.addArc() but couldn't get the result required. I could only cut the image in a rectangle.
Path path = new Path();
path.addArc(rectF, 0, 180);
canvas.clipPath(path, Region.Op.DIFFERENCE);
canvas.drawBitmap(orig, rect, rect, circlePaint);
You need to use this method to get circular shape from a rectangle bitmap
public static Bitmap getCircularBitmap(Bitmap bitmap) {
Bitmap output;
if (bitmap.getWidth() > bitmap.getHeight()) {
output = Bitmap.createBitmap(bitmap.getHeight(), bitmap.getHeight(), Config.ARGB_8888);
} else {
output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getWidth(), 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());
float r = 0;
if (bitmap.getWidth() > bitmap.getHeight()) {
r = bitmap.getHeight() / 2;
} else {
r = bitmap.getWidth() / 2;
}
RadialGradient gradient = new RadialGradient(bitmap.getWidth() / 2, bitmap.getWidth() / 2, bitmap.getWidth() / 2,
new int[] {0xFFFFFFFF, 0xFFFFFFFF, 0x00FFFFFF},
new float[] {0.0f, 0.4f, 0.8f},
android.graphics.Shader.TileMode.CLAMP);
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
paint.setShader(gradient);
canvas.drawCircle(r, r, r, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}
and then you can cut the circle into half like this
Bitmap semicircle=Bitmap.createBitmap(circlebitmap, 0, 0, circlebitmap.getWidth()/2 , circlebitmap.getHeight());

Categories

Resources