Marking few markers and adding names using Canvas and Paint on map. But am able to see the text only 9 characters rest are hiding (not visible). How to do it?
private Bitmap drawTitleOnMarkerIcon(MarkingInfo markingInfo) {
Bitmap bm = BitmapFactory.decodeResource(getResources(), AddLocationTypeIcon.getIcon(markingInfo.getType())).copy(
Bitmap.Config.ARGB_8888, true);
Canvas canvas = new Canvas(bm);
Paint paint = new Paint();
paint.setColor(Color.BLUE);
paint.setAntiAlias(true);
paint.setFakeBoldText(true);
paint.setTextSize(16);
paint.setTextAlign(Align.LEFT);
canvas.drawText(markingInfo.getName(), 0, 60, paint);
BitmapDrawable draw = new BitmapDrawable(getResources(), bm);
return draw.getBitmap();
}
I should able to see complete text, When I have more than 15 character just I need to wrap it to next line. search many sites and posted query previously but I got no solution. please do help to achieve this task
private Bitmap textAsBitmap(String text, float textSize, int textColor) {
Paint paint = new Paint();
paint.setTextSize(textSize);
paint.setColor(textColor);
paint.setFakeBoldText(true);
paint.setTextAlign(Paint.Align.LEFT);
int width = (int) (paint.measureText(text) + 0.5f); // round
float baseline = (int) (-paint.ascent() + 0.5f); // ascent()is negative
int height = (int) (baseline + paint.descent() + 0.5f);
Bitmap image = Bitmap.createBitmap(width,height,Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(image);
canvas.drawText(text, 0, baseline, paint);
return image;
}
MarkerOptions().title(Name()).icon(BitmapDescriptorFactory.fromBitmap(textAsBitmap));
I am using this very common class to round corners:
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;
}
I'd like to modify it so that only Top Left corner is rounded. I can't find the parameter in the code that does this? Can someone assist?
It's probably not the most efficient way to do this, but you could fill in the rounded off corners by painting on top of your current mask. You could start with the current code then use canvas.drawRect (right after the call to canvas.drawRoundRect) on the appropriate regions (the corners). I imagine something like this would round only the top left corner:
public static Bitmap getRoundedTopLeftCornerBitmap(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;
final Rect topRightRect = new Rect(bitmap.getWidth()/2, 0, bitmap.getWidth(), bitmap.getHeight()/2);
final Rect bottomRect = new Rect(0, bitmap.getHeight()/2, bitmap.getWidth(), bitmap.getHeight());
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
// Fill in upper right corner
canvas.drawRect(topRightRect, paint);
// Fill in bottom corners
canvas.drawRect(bottomRect, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}
There's a bit of optimization you could do here if you feel like it, but I think it should work. The general idea definitely should. I haven't tried or tested this code though and it won't look right if pixels > bitmap.getWidth()/2 or pixels > bitmap.getHeight()/2. Then again, that was probably true before too.
public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, int topLeftX, int topLeftY, int topRightX, int topRightY, int bottomRightX, int bottomRightY, int bottomLeftX, int bottomLeftY) {
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
// the float array passed to this function defines the x/y values of the corners
// it starts top-left and works clockwise
// so top-left-x, top-left-y, top-right-x etc
RoundRectShape rrs = new RoundRectShape(new float[]{topLeftX, topLeftY, topRightX, topRightY, bottomRightX, bottomRightY, bottomLeftX, bottomLeftY}, null, null);
canvas.drawARGB(0, 0, 0, 0);
paint.setAntiAlias(true);
paint.setColor(0xFF000000);
rrs.resize(bitmap.getWidth(), bitmap.getHeight());
rrs.draw(canvas, paint);
paint.setXfermode(new PorterDuffXfermode(android.graphics.PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}
Or you can see RoundRects.java source code - example that show how to produce round corners, available in SDK samples: http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android-apps/4.3_r2.1/com/example/android/apis/graphics/RoundRects.java/
this is for select corners:
public static Bitmap getRoundedCornerBitmap(Context context, Bitmap bitmap, float roundDip, boolean roundTL, boolean roundTR, boolean roundBL, boolean roundBR)
{
try
{
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 = convertDipToPixel(roundDip, context);
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);// draw round
// 4Corner
if (!roundTL)
{
Rect rectTL = new Rect(0, 0, bitmap.getWidth() / 2, bitmap.getHeight() / 2);
canvas.drawRect(rectTL, paint);
}
if (!roundTR)
{
Rect rectTR = new Rect(bitmap.getWidth() / 2, 0, bitmap.getWidth(), bitmap.getHeight() / 2);
canvas.drawRect(rectTR, paint);
}
if (!roundBR)
{
Rect rectBR = new Rect(bitmap.getWidth() / 2, bitmap.getHeight() / 2, bitmap.getWidth(), bitmap.getHeight());
canvas.drawRect(rectBR, paint);
}
if (!roundBL)
{
Rect rectBL = new Rect(0, bitmap.getHeight() / 2, bitmap.getWidth() / 2, bitmap.getHeight());
canvas.drawRect(rectBL, paint);
}
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
} catch (Exception e)
{
}
return bitmap;
}
This is more of a conceptual answer, but could you draw a rounded rectangle then layer two normal rectangles on top of the corner that you would like to be rounded?
In case you needed to draw (on canvas) a round rect with different radii for different corners, you can use this:
private void drawAsymmetricRoundRect(Canvas canvas, RectF rectF, float[] radii, Paint paint) {
float topLeftX = rectF.left + radii[0];
float topLeftY = rectF.top + radii[0];
float topRightX = rectF.right - radii[1];
float topRightY = rectF.top + radii[1];
float bottomRightX = rectF.right - radii[2];
float bottomRightY = rectF.bottom - radii[2];
float bottomLeftY = rectF.bottom - radii[3];
float bottomLeftX = rectF.left + radii[3];
RectF topLeftCorner = new RectF(rectF.left, rectF.top, topLeftX + radii[0], topLeftY + radii[0]);
RectF topRightCorner = new RectF(topRightX - radii[1], rectF.top, rectF.right, topRightY + radii[1]);
RectF bottomRightCorner = new RectF(bottomRightX - radii[2], bottomRightY - radii[2], rectF.right, rectF.bottom);
RectF bottomLeftCorner = new RectF(rectF.left, bottomLeftY - radii[3], bottomLeftX + radii[3], rectF.bottom);
canvas.drawArc(topLeftCorner, 180, 90, true, paint);
canvas.drawArc(topRightCorner, 270, 90, true, paint);
canvas.drawArc(bottomRightCorner, 0, 90, true, paint);
canvas.drawArc(bottomLeftCorner, 90, 90, true, paint);
canvas.drawRect(topLeftX, rectF.top, topRightX, bottomLeftY < bottomRightY ? bottomLeftY : bottomRightY, paint); //top rect
canvas.drawRect(topLeftX > bottomLeftX ? topLeftX : bottomLeftX, topRightY, rectF.right, bottomRightY, paint); //right rect
canvas.drawRect(bottomLeftX, topLeftY > topRightY ? topLeftY : topRightY, bottomRightX, rectF.bottom, paint); //bottom rect
canvas.drawRect(rectF.left, topLeftY, bottomRightX < topRightX ? bottomRightX : topRightX, bottomLeftY, paint); //left rect
}
float[] radii is a float array (length = 4), that stores sizes of radii of your corners (clockwise, starting from top-left corner => {topLeft, topRight, bottomRight, bottomLeft}).
Basically this approach draws 4 arcs (corners) and fills everything in between those corners with 4 rects.
IMPORTANT NOTE: I placed the initialization of corners RectFs within this method to reduce the complexity of posted code. Due to the fact that you will problably call this method from your onDraw() method, you should extract this part of the code, and place it where you init other Rects(as long as you're not initializing them in onDraw() as well :P).
Path clipPath = new Path();
RectF rect = new RectF(0, 0, this.getWidth(), this.getHeight());
clipPath.addRoundRect(rect, new float[]{radius, radius, 0, 0, 0, 0, 0, 0},
Path.Direction.CW);
canvas.clipPath(clipPath);
This code produces image with rounded top left corner - each pair of float parameters describe angle for each corner
Key function is:
public void addRoundRect(RectF rect, float[] radii, Direction dir)
in Path class
Description from doc:
Add a closed round-rectangle contour to the path. Each corner receives
two radius values [X, Y]. The corners are ordered top-left, top-right,
bottom-right, bottom-left
#param rect The bounds of a round-rectangle to add to the path
#param radii Array of 8 values, 4 pairs of [X,Y] radii
#param dir The direction to wind the round-rectangle's contour
I'm trying to use canvas.clipPath() to draw a bitmap image inside a constraining circle similar to to Clipping activity in the APP demos. The problem is that my code only renders properly on the emulator, when run on an actual Samsung Galaxy Nexus 4.2 it appears as if the clipPath works more like a rectangular clipping. I'm totally stumped! I create a new Path() and decode a bitmap in my view ctor. Any suggestions?
#Override
protected void onDraw(Canvas canvas) {
Point point = getPoint();
path.reset();
canvas.clipPath(path); // makes the clip empty
path.addCircle(point.x, point.y, getScale() * 140, Path.Direction.CCW);
canvas.clipPath(path, Region.Op.REPLACE);
Point scaledSize = new Point((int) (bitmapSize.x * getScale()), (int) (bitmapSize.y * getScale()));
Point topLeft = new Point((point.x - (scaledSize.x / 2)), (point.y - (scaledSize.y / 2)));
canvas.drawBitmap(bitmap, null, new Rect(topLeft.x, topLeft.y, topLeft.x + scaledSize.x, topLeft.y + scaledSize.y), paint);
}
Galaxy Nexus
Emulator
ClipPath is not supported for hardware acceleration
You can close hardware acceleration use this:
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
clipPath is not supported for hardware acceleration.
You can create a clipped bitmap using something like this:
Bitmap clippedBitmap = ... // Create same size bitmap as source
Paint paint = new Paint();
Canvas canvas = new Canvas(clippedBitmap);
paint.setColor(Color.RED);
paint.setStyle(PAint.Style.FILL);
paint.setFilterBitmap(true);
canvas.drawCircle(cx, cy, radius, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(sourceBitmap, 0, 0, paint);
Do this once, and then draw the clipped bitmap instead of the source one
ClipPath is not supported for hardware acceleration. Check the link below under the topic Unsupported Drawing Operations.
http://developer.android.com/guide/topics/graphics/hardware-accel.html#drawing-support
You can use the below for reference and modify the paramters of draw circle to suit your needs.
public class MainActivity extends Activity
{
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
DrawingView dv = new DrawingView(this);
dv.setBackgroundColor(Color.RED);
setContentView(dv);
}
class DrawingView extends View{
Bitmap bitmap;
public DrawingView(Context context)
{
super(context);
bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.sqaure);
}
#Override
public void onDraw(Canvas canvas)
{
Paint paint = new Paint();
//paint.setStyle(Paint.Style.FILL);
// paint.setColor(Color.CYAN);
canvas.drawBitmap(getclip(), 0, 0, paint);//originally x and y is o and o .
}
public Bitmap getclip()
{
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.setColor(Color.RED);
paint.setStyle(Paint.Style.FILL);
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
//paint.setColor(color);
canvas.drawCircle(bitmap.getWidth() / 2-40,
bitmap.getHeight() / 2, bitmap.getWidth() / 2-40, paint);
// change the parameters accordin to your needs.
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}
}
}
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