Add a drawable within a specified "Path" variable in android? - 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.

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;
}

Bitmap not circle properly

i trying to do bitmap circle it work but high resolution image not work properly.It is working like small circle in image view.
i have tried this code and i tried many other code,but didn't work properly
public static Bitmap circleShape(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;
}
I have tried so many code and that was not working perfectly. I have searched and found this code. It work awesome, amazing.. hope anybody helpfull this code.. thanks
public static Bitmap circleShape(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;
}

Draw and fill custom shape

I'm trying to create a custom shape using the Path object in Android and I'm running into a weird problem.
What I'm trying to achieve is depicted in the picture below
Here is the code I'm using to draw and fill the shape:
public class BallView extends RelativeLayout {
....
protected void onDraw(Canvas canvas) {
...
PaintArc(canvas);
}
private void PaintArc(Canvas canvas) {
Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
p.setAntiAlias(true);
p.setStyle(Paint.Style.FILL_AND_STROKE);
p.setStrokeWidth(2);
p.setColor(Color.RED);
RectF oval = new RectF(20, 20, getWidth() - 20, getHeight() - 20);
RectF oval2 = new RectF(0, 0, getWidth(), getHeight());
Path path = new Path();
path.setFillType(Path.FillType.EVEN_ODD);
path.addArc(oval, 0, 180);
path.addArc(oval2, 0, 180);
float y=20+oval.height()/2;
float x=20;
path.moveTo(x,y);
path.lineTo(x - 20, y);
x=oval.width()+20;
path.moveTo(x,y);
path.lineTo(x+20,y);
path.close();
canvas.drawPath(path, p);
}
}
The actual result that I'm getting looks like this:
The resulting shape without Filling looks like this:
Can you tell me what I'm doing wrong ?
try this:
class MyView extends View {
private Path mPath;
private Paint mPaint;
private RectF mOval;
public MyView(Context context) {
super(context);
mPath = new Path();
mPaint = new Paint();
mPaint.setColor(0xffff0000);
mOval = new RectF();
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
int dx = w / 4;
mOval.set(0, 0, w, w);
mPath.reset();
mPath.moveTo(0, w / 2f);
mPath.arcTo(mOval, 180, 180);
mPath.rLineTo(-dx, 0);
mOval.inset(dx, dx);
mPath.addArc(mOval, 0, -180);
mPath.rLineTo(-dx, 0);
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(0xffffffff);
mPaint.setStyle(Style.FILL);
canvas.drawPath(mPath, mPaint);
canvas.translate(0, getWidth() / 2);
mPaint.setStyle(Style.STROKE);
canvas.drawPath(mPath, mPaint);
}
}
- I have just edited my answer
and i add below code
RectF oval3 = new RectF(10, 20, getWidth() - 10, getHeight() - 10);
/**
*Now check this code output seem like your thought
*/
private void PaintArc(Canvas canvas) {
Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
p.setAntiAlias(true);
p.setStyle(Paint.Style.STROKE);
p.setStrokeWidth(2);
p.setColor(Color.RED);
Paint p1 = new Paint(Paint.ANTI_ALIAS_FLAG);
p1.setAntiAlias(true);
p1.setStyle(Paint.Style.STROKE);
p1.setStrokeWidth(10);
p1.setColor(Color.RED);
RectF oval = new RectF(20, 20, getWidth() - 20, getHeight() - 20);
RectF oval2 = new RectF(0, 0, getWidth(), getHeight());
RectF oval3 = new RectF(10, 20, getWidth() - 10, getHeight() - 10);
Path path = new Path();
path.setFillType(Path.FillType.EVEN_ODD);
path.addArc(oval, 0, 180);
path.addArc(oval2, 0, 180);
path.addArc(oval3, 0, 180);
float y = 20 + oval.height() / 2;
float x = 20;
path.moveTo(x, y);
path.lineTo(x - 20, y);
x = oval.width() + 20;
path.moveTo(x, y);
path.lineTo(x + 20, y);
path.close();
canvas.drawArc(oval3, 0, 180, false, p1);
canvas.drawPath(path, p);
}

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());

How to draw a stroke in a Bitmap using canvas?

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);
}

Categories

Resources