I use UniversalImageLoader library to create a rounded imageview :
DisplayImageOptions options = new DisplayImageOptions.Builder()
.displayer(new RoundedBitmapDisplayer(2000))
.cacheOnDisc(true)
.build();
ImageLoader imageLoader = ImageLoader.getInstance();
imageLoader.displayImage(avatar, rounded, options);
How can i add a thin border (1dp) around the rounded imageView ?
This issue was addressed some times ago but was not implemented in the UIL so here is what you have to do change the BitmapDisplayer to CircleBitmapDisplayer like this
package com.nostra13.universalimageloader.core.display;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.Log;
import com.nostra13.universalimageloader.core.assist.LoadedFrom;
import com.nostra13.universalimageloader.core.imageaware.ImageAware;
import com.nostra13.universalimageloader.core.imageaware.ImageViewAware;
public class CircleBitmapDisplayer implements BitmapDisplayer {
private float radius, centerX, centerY, borderWidth = 0;
private int borderColor = Color.BLACK;
private boolean biggestCircle = false, isCentered = true;
public CircleBitmapDisplayer() {
this.biggestCircle = true;
}
public CircleBitmapDisplayer(float centerX, float centerY) {
this();
this.centerX = centerX;
this.centerY = centerY;
this.isCentered = false;
}
public CircleBitmapDisplayer(float borderWidth, int borderColor) {
this();
this.borderWidth = borderWidth;
this.borderColor = borderColor;
}
public CircleBitmapDisplayer(float radius) {
this.radius = radius;
}
public CircleBitmapDisplayer(float radius, float borderWidth,
int borderColor) {
this(radius);
this.borderWidth = borderWidth;
this.borderColor = borderColor;
}
public CircleBitmapDisplayer(float radius, float centerX, float centerY) {
this(radius);
this.centerX = centerX;
this.centerY = centerY;
this.isCentered = false;
}
public CircleBitmapDisplayer(float radius, float centerX, float centerY,
float borderWidth, int borderColor) {
this(radius, centerX, centerY);
this.borderWidth = borderWidth;
this.borderColor = borderColor;
}
#Override
public void display(Bitmap bitmap, ImageAware imageAware,
LoadedFrom loadedFrom) {
if (!(imageAware instanceof ImageViewAware)) {
throw new IllegalArgumentException(
"ImageAware should wrap ImageView. ImageViewAware is expected.");
}
int ivWidth = imageAware.getWidth();
int ivHeight = imageAware.getHeight();
int bmWidth = bitmap.getWidth();
int bmHeight = bitmap.getHeight();
if (isCentered) {
centerX = (float) ivWidth / 2;
centerY = (float) ivHeight / 2;
}
if (biggestCircle) {
if (isCentered) {
radius = ivWidth < ivHeight ? (float) ivWidth / 2
: (float) ivHeight / 2;
} else {
radius = Math.min(centerX < ivWidth - centerX ? centerX
: ivWidth - centerX,
centerY < ivHeight - centerY ? centerX : ivHeight
- centerY);
}
}
Rect srcRect;
if (bmWidth < bmHeight) {
srcRect = new Rect(0, (bmHeight - bmWidth) / 2, bmWidth, bmWidth
+ (bmHeight - bmWidth) / 2);
} else {
srcRect = new Rect((bmWidth - bmHeight) / 2, 0, bmHeight
+ (bmWidth - bmHeight) / 2, bmHeight);
}
RectF destRectF = new RectF(0, 0, ivWidth, ivHeight);
imageAware.setImageBitmap(getCircledBitmap(bitmap, centerX, centerY,
radius, srcRect, destRectF, ivWidth, ivHeight, borderWidth,
borderColor));
}
public static Bitmap getCircledBitmap(Bitmap bitmap, float centerX,
float centerY, float radius, Rect srcRect, RectF destRectF,
int width, int height, float borderWidth, int borderColor) {
Bitmap output = Bitmap.createBitmap(width, height, Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final Paint paint = new Paint();
paint.setAntiAlias(true);
// if 1 pixel is missing, do: radius - borderWidth + 1
canvas.drawCircle(centerX, centerY, radius - borderWidth, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(bitmap, srcRect, destRectF, paint);
if (0 < borderWidth) {
paint.setXfermode(null);
paint.setStyle(Style.STROKE);
paint.setColor(borderColor);
paint.setStrokeWidth(borderWidth);
canvas.drawCircle(centerX, centerY, radius - borderWidth / 2, paint);
}
return output;
}
}
I guess such customization may not be offered by UniversalImageLoader Internally, however this work arround can fit your need:
The Imageview on which you wish to show the downloaded image, just set its background property to white color, and also set its padding attribute to 1DP. Then set its SRC property to the image you have downloaded using UniversalImageLoader.
This should do the trick!
Related
I am trying to use the support lib v4's RoundedBitmapDrawable in order to display Rounded bitmaps loaded asynchronously in ImageViews, either circled or rounded rectangles.
However, it looks like RoundedBitmapDrawable does not mesh very well with LayerDrawable :
If I try something like :
if (previousDrawable != null) {
final Drawable[] layers = new Drawable[2];
layers[0] = previousDrawable;
layers[1] = roundedDrawable;
TransitionDrawable drawable = new TransitionDrawable(layers);
view.setImageDrawable(drawable);
drawable.startTransition(3000);
} else {
view.setImageDrawable(roundedDrawable);
}
The TransitionDrawable launches but it does not respect the RoundedBitmapDrawable is not correctly displayed : its dimensions seems to shift somehow, if I set it to be a circle with :
RoundedBitmapDrawable roundedDrawable = RoundedBitmapDrawableFactory
.create(getResources(), bitmap);
roundedDrawable.setCornerRadius(bitmap.getHeight() / 2);
roundedDrawable.setAntiAlias(true);
It is displayed correctly if I use ImageView.setImageDrawable(), but it results in a rounded rectangle if a TransitionDrawable displays it.
Does anybody has any idea why this display problem happen ?
Set
roundedDrawable.setCircular(true);
then it works fine
Use Universal Image loader to fix your issue
https://github.com/nostra13/Android-Universal-Image-Loader
This is my solution to create a rounded image:
package com.campusapp;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.ImageView;
public class CircularImageView extends ImageView {
private int borderWidth;
private int canvasSize;
private Bitmap image;
private Paint paint;
private Paint paintBorder;
public CircularImageView(final Context context) {
this(context, null);
}
public CircularImageView(Context context, AttributeSet attrs) {
this(context, attrs, R.attr.circularImageViewStyle);
}
public CircularImageView(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
// init paint
paint = new Paint();
paint.setAntiAlias(true);
paintBorder = new Paint();
paintBorder.setAntiAlias(true);
// load the styled attributes and set their properties
TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.CircularImageView, defStyle, 0);
if(attributes.getBoolean(R.styleable.CircularImageView_border, true))
{
int defaultBorderSize = (int) (4 * getContext().getResources().getDisplayMetrics().density + 0.5f);
setBorderWidth(attributes.getDimensionPixelOffset(R.styleable.CircularImageView_border_width, defaultBorderSize));
setBorderColor(attributes.getColor(R.styleable.CircularImageView_border_color, Color.WHITE));
}
if(attributes.getBoolean(R.styleable.CircularImageView_shadow, false))
addShadow();
}
public void setBorderWidth(int borderWidth)
{
this.borderWidth = borderWidth;
this.requestLayout();
this.invalidate();
}
public void setBorderColor(int borderColor)
{
if (paintBorder != null)
paintBorder.setColor(borderColor);
this.invalidate();
}
public void addShadow()
{
setLayerType(LAYER_TYPE_SOFTWARE, paintBorder);
paintBorder.setShadowLayer(4.0f, 0.0f, 2.0f, Color.BLACK);
}
#Override
public void onDraw(Canvas canvas)
{
// load the bitmap
image = drawableToBitmap(getDrawable());
// init shader
if (image != null)
{
canvasSize = canvas.getWidth();
if(canvas.getHeight()<canvasSize)
canvasSize = canvas.getHeight();
BitmapShader shader = new BitmapShader(Bitmap.createScaledBitmap(image, canvasSize, canvasSize, false), Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
paint.setShader(shader);
// circleCenter is the x or y of the view's center
// radius is the radius in pixels of the cirle to be drawn
// paint contains the shader that will texture the shape
int circleCenter = (canvasSize - (borderWidth * 2)) / 2;
canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth, ((canvasSize - (borderWidth * 2)) / 2) + borderWidth - 4.0f, paintBorder);
canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth, ((canvasSize - (borderWidth * 2)) / 2) - 4.0f, paint);
}
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
int width = measureWidth(widthMeasureSpec);
int height = measureHeight(heightMeasureSpec);
setMeasuredDimension(width, height);
}
private int measureWidth(int measureSpec)
{
int result = 0;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if (specMode == MeasureSpec.EXACTLY)
{
// The parent has determined an exact size for the child.
result = specSize;
}
else if (specMode == MeasureSpec.AT_MOST)
{
// The child can be as large as it wants up to the specified size.
result = specSize;
}
else
{
// The parent has not imposed any constraint on the child.
result = canvasSize;
}
return result;
}
private int measureHeight(int measureSpecHeight)
{
int result = 0;
int specMode = MeasureSpec.getMode(measureSpecHeight);
int specSize = MeasureSpec.getSize(measureSpecHeight);
if (specMode == MeasureSpec.EXACTLY)
{
// We were told how big to be
result = specSize;
}
else if (specMode == MeasureSpec.AT_MOST)
{
// The child can be as large as it wants up to the specified size.
result = specSize;
}
else
{
// Measure the text (beware: ascent is a negative number)
result = canvasSize;
}
return (result + 2);
}
public Bitmap drawableToBitmap(Drawable drawable)
{
if (drawable == null)
{
return null;
}
else if (drawable instanceof BitmapDrawable)
{
return ((BitmapDrawable) drawable).getBitmap();
}
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(),
drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
}
After creating the class, replace your ImageView with the code below:
<com.yourpkg.CircularImageView
android:layout_width="150dp"
android:layout_height="150dp"
android:src="#drawable/your_image"
app:border_color="#EEEEEE"
app:border_width="4dp"
app:shadow="true" />
public static Bitmap getRoundedCornerBitmap(Context context, Bitmap input, int pixels , int w , int h , boolean squareTL, boolean squareTR, boolean squareBL, boolean squareBR ) {
Bitmap output = Bitmap.createBitmap(w, h, Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final float densityMultiplier = context.getResources().getDisplayMetrics().density;
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, w, h);
final RectF rectF = new RectF(rect);
//make sure that our rounded corner is scaled appropriately
final float roundPx = pixels*densityMultiplier;
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
//draw rectangles over the corners we want to be square
if (squareTL ){
canvas.drawRect(0, 0, w/2, h/2, paint);
}
if (squareTR ){
canvas.drawRect(w/2, 0, w, h/2, paint);
}
if (squareBL ){
canvas.drawRect(0, h/2, w/2, h, paint);
}
if (squareBR ){
canvas.drawRect(w/2, h/2, w, h, paint);
}
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(input, 0,0, paint);
return output;
}
or you can see this also
I am looking for an animation liberary of code which will help me to do 360 degree animation using set of images (Around 60 images for horizontal rotation). Also images are in SDCARD and not in application.
Thank You
You can create a custom view and override onDraw(Canvas) method and draw the bitmap of desired image.
You can keep track on the current "direction" in degree and calculate which should be displayed in what location using Canvas.drawBitmap(Bitmap,Matrix,Paint).
Here's an example of moving one image according to phone orientation.
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnTouchListener;
public class SkySurfaceView extends SurfaceView implements OnTouchListener {
private static final String TAG = SkySurfaceView.class.getSimpleName();
private double viewPortX, viewPortY;
private int starX, starY;
private Bitmap target;
private int targetWidth, targetHeight;
private int vpWidth, vpHeight;
private Matrix skyMatrix, skyMatrix2;
private Matrix skyMatrix3;
private Bitmap star;
private Paint paint;
private Rect touchRect, touchRect2, touchRect3;
public SkySurfaceView(Context context, AttributeSet attr) {
super(context, attr);
viewPortX = viewPortY = 0;
skyMatrix = new Matrix();
skyMatrix2 = new Matrix();
skyMatrix3 = new Matrix();
paint = new Paint();
paint.setStrokeWidth(1);
paint.setDither(true);
paint.setColor(Color.RED);
Options opt = new Options();
opt.inSampleSize = 2;
opt.inScaled = false;
opt.inPreferredConfig = Config.RGB_565;
star = BitmapFactory.decodeResource(getResources(), R.drawable.star,
opt);
touchRect = new Rect(0, 0, star.getWidth(), star.getHeight());
touchRect2 = new Rect(0, 0, star.getWidth(), star.getHeight());
touchRect3 = new Rect(0, 0, star.getWidth(), star.getHeight());
this.setWillNotDraw(true);
setLayerType(View.LAYER_TYPE_HARDWARE, null);
this.setOnTouchListener(this);
getHolder().setFormat(PixelFormat.RGB_565);
}
public void setTarget(Bitmap b) {
target = b;
targetHeight = target.getHeight();
targetWidth = target.getWidth();
}
public void init() {
this.starX = (int) (vpWidth * Math.random()) + vpWidth;
this.starY = (int) ((vpHeight - star.getHeight()) * Math.random());
Log.i(TAG, "drawn star on " + starX + "," + starY);
Canvas c = new Canvas();
Log.i(TAG,
"target dimension is " + target.getWidth() + "x"
+ target.getHeight());
Bitmap bitmap = Bitmap.createBitmap(target.getWidth(),
target.getHeight(), Config.RGB_565);
c.setBitmap(bitmap);
c.drawBitmap(target, 0, 0, paint);
c.drawBitmap(star, starX, starY, paint);
c.drawBitmap(star, starX - targetWidth, starY, paint);
target.recycle();
setTarget(bitmap);
setWillNotDraw(false);
}
#Override
public boolean performClick() {
super.performClick();
return false;
}
/**
*
* #param x
* - [-1:1]
* #param y
* - [-1:1]
*/
public void setViewPort(double x, double y) {
viewPortX = x;
viewPortY = y;
int tempX = (int) (targetWidth * (viewPortX));
int tempY = (int) (targetHeight * (viewPortY - 1));
tempY = Math.max(tempY, -(targetHeight - vpHeight) / 2);
tempY = Math.min(tempY, +(targetHeight - vpHeight / 2));
Log.i(TAG,
String.format("%d %d , %d %d, %d %d", tempX, tempY, tempX
- targetWidth, tempY, tempX + targetWidth, tempY));
skyMatrix.reset();
skyMatrix.postTranslate(tempX, tempY);
skyMatrix2.reset();
skyMatrix2.postTranslate(tempX - targetWidth, tempY);
skyMatrix3.reset();
skyMatrix3.postTranslate(tempX + targetWidth, tempY);
int xx = (tempX + starX);
while (xx < targetWidth) {
xx += targetWidth;
}
touchRect.offsetTo(xx % targetWidth, (tempY + starY) % targetHeight);
touchRect2.offsetTo(xx % targetWidth - targetWidth, (tempY + starY)
% targetHeight);
touchRect3.offsetTo(xx % targetWidth + targetWidth, (tempY + starY)
% targetHeight);
postInvalidate();
}
public void setViewportSize(int x, int y) {
vpWidth = x;
vpHeight = y;
}
#Override
protected void onDraw(Canvas c) {
super.onDraw(c);
c.drawBitmap(target, skyMatrix, paint);
c.drawBitmap(target, skyMatrix2, paint);
c.drawBitmap(target, skyMatrix3, paint);
}
#Override
public boolean onTouch(View v, MotionEvent event) {
float ex = event.getX();
float ey = event.getY();
Log.i(TAG, "touched " + ex + " " + ey);
if (touchRect.contains((int) ex, (int) ey)) {
if (listener != null) {
listener.onCaptured();
}
} else if (touchRect2.contains((int) ex, (int) ey)) {
if (listener != null) {
listener.onCaptured();
}
} else if (touchRect3.contains((int) ex, (int) ey)) {
if (listener != null) {
listener.onCaptured();
}
}
return false;
}
public void setListener(OnStarCaptureListener listener) {
this.listener = listener;
}
}
In this example, "target" is a sky image. Whenever setViewPort is called, (x and y [-1:1]), the image's drawing matrix is updated and "invalidate()" is called. The onDraw() method call will draw the "target" with offset.
how can I achieve the hexagon imageview that is shown below.
http://imgur.com/1PEGuQu
Note that I tried the solution which is at this question:
How to give hexagon shape to ImageView
And I also tried this solution:
Masking(crop) image in frame
But I don't want to fill a color outside of the hexagon. I want it to be transparent, so the views and images behind can be seen.
By the way I tried, BitmapShader, PorterDuffXFermode etc. but cannot managed to get the result I wanted.
Thanks in advance.
I at last solved my problem. I find a very useful library that specifically does the trick I wanted. It is masking the imageview with a svg type vector image.
Library:
CustomShapeImageView
Result:
Screenshot
Edit: I also want to share the hexagonal svg with you, in case of necessity.
<svg width="205" height="237" xmlns="http://www.w3.org/2000/svg">
<title>hexagon</title>
<metadata id="metadata3064">image/svg+xml</metadata>
<g>
<title>Layer 1</title>
<polygon points="0,59.27092742919922 0,177.8127899169922 102.66026306152344,237.08370971679688 205.3205108642578,177.8127899169922 205.3205108642578,59.27092742919922 102.66026306152344,0 " id="svg_1" fill="#000000"/>
</g>
</svg>
Here is my code for this, this supports shadows to:
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.util.AttributeSet;
import android.widget.ImageView;
public class HexagonImageView extends ImageView {
private Path hexagonPath;
private Path hexagonBorderPath;
private float radius;
private Bitmap image;
private int viewWidth;
private int viewHeight;
private Paint paint;
private BitmapShader shader;
private Paint paintBorder;
private int borderWidth = 4;
public HexagonImageView(Context context) {
super(context);
setup();
}
public HexagonImageView(Context context, AttributeSet attrs) {
super(context, attrs);
setup();
}
public HexagonImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setup();
}
private void setup() {
paint = new Paint();
paint.setAntiAlias(true);
paintBorder = new Paint();
setBorderColor(Color.WHITE);
paintBorder.setAntiAlias(true);
this.setLayerType(LAYER_TYPE_SOFTWARE, paintBorder);
paintBorder.setShadowLayer(4.0f, 1.0f, 1.0f, Color.BLACK);
hexagonPath = new Path();
hexagonBorderPath = new Path();
}
public void setRadius(float r) {
this.radius = r;
calculatePath();
}
public void setBorderWidth(int borderWidth) {
this.borderWidth = borderWidth;
this.invalidate();
}
public void setBorderColor(int borderColor) {
if (paintBorder != null)
paintBorder.setColor(borderColor);
this.invalidate();
}
private void calculatePath() {
float triangleHeight = (float) (Math.sqrt(3) * radius / 2);
float centerX = viewWidth/2;
float centerY = viewHeight/2;
hexagonBorderPath.moveTo(centerX, centerY + radius);
hexagonBorderPath.lineTo(centerX - triangleHeight, centerY + radius/2);
hexagonBorderPath.lineTo(centerX - triangleHeight, centerY - radius/2);
hexagonBorderPath.lineTo(centerX, centerY - radius);
hexagonBorderPath.lineTo(centerX + triangleHeight, centerY - radius/2);
hexagonBorderPath.lineTo(centerX + triangleHeight, centerY + radius/2);
hexagonBorderPath.moveTo(centerX, centerY + radius);
float radiusBorder = radius - borderWidth;
float triangleBorderHeight = (float) (Math.sqrt(3) * radiusBorder / 2);
hexagonPath.moveTo(centerX, centerY + radiusBorder);
hexagonPath.lineTo(centerX - triangleBorderHeight, centerY + radiusBorder/2);
hexagonPath.lineTo(centerX - triangleBorderHeight, centerY - radiusBorder/2);
hexagonPath.lineTo(centerX, centerY - radiusBorder);
hexagonPath.lineTo(centerX + triangleBorderHeight, centerY - radiusBorder/2);
hexagonPath.lineTo(centerX + triangleBorderHeight, centerY + radiusBorder/2);
hexagonPath.moveTo(centerX, centerY + radiusBorder);
invalidate();
}
private void loadBitmap() {
BitmapDrawable bitmapDrawable = (BitmapDrawable) this.getDrawable();
if (bitmapDrawable != null)
image = bitmapDrawable.getBitmap();
}
#SuppressLint("DrawAllocation")
#Override
public void onDraw(Canvas canvas){
super.onDraw(canvas);
loadBitmap();
// init shader
if (image != null) {
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
shader = new BitmapShader(Bitmap.createScaledBitmap(image, canvas.getWidth(), canvas.getHeight(), false), Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
paint.setShader(shader);
canvas.drawPath(hexagonBorderPath, paintBorder);
canvas.drawPath(hexagonPath, paint);
}
}
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = measureWidth(widthMeasureSpec);
int height = measureHeight(heightMeasureSpec, widthMeasureSpec);
viewWidth = width - (borderWidth * 2);
viewHeight = height - (borderWidth * 2);
radius = height / 2 - borderWidth;
calculatePath();
setMeasuredDimension(width, height);
}
private int measureWidth(int measureSpec) {
int result = 0;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if (specMode == MeasureSpec.EXACTLY) {
result = specSize;
}
else {
result = viewWidth;
}
return result;
}
private int measureHeight(int measureSpecHeight, int measureSpecWidth) {
int result = 0;
int specMode = MeasureSpec.getMode(measureSpecHeight);
int specSize = MeasureSpec.getSize(measureSpecHeight);
if (specMode == MeasureSpec.EXACTLY) {
result = specSize;
}
else {
result = viewHeight;
}
return (result + 2);
}
}
I've read this and looks valid. They even have a video tutorial: http://www.41post.com/4794/programming/android-rendering-a-path-with-a-bitmap-fill on how to fill a shape with a texture
Hi I am trying to create Circle using canvas like following image.
But now I can only able to make like following.
I don't understand how can I make this. I need to cut the circle from one side and need to fill that circle border only.
Here is my code For review.
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// Clear canvas
canvas.drawColor(Color.TRANSPARENT);
// Draw Ticks and colored arc
drawTicks(canvas);
}
private void drawTicks(Canvas canvas) {
float availableAngle = 160;
float majorStep = (float) (majorTickStep/ maxSpeed *availableAngle);
float majorTicksLength = 30;
RectF oval = getOval(canvas, 1);
float radius = oval.width()*0.35f;
float currentAngle = 10;
double curProgress = 0;
while (currentAngle <= 170) {
if (labelConverter != null) {
canvas.save();
canvas.rotate(180 + currentAngle, oval.centerX(), oval.centerY());
float txtX = oval.centerX() + radius + majorTicksLength/2 + 8;
float txtY = oval.centerY();
canvas.rotate(+90, txtX, txtY);
//canvas.drawText(labelConverter.getLabelFor(curProgress, maxSpeed), txtX, txtY, txtPaint);
canvas.restore();
}
currentAngle += majorStep;
curProgress += majorTickStep;
}
RectF smallOval = getOval(canvas, 0.7f);
colorLinePaint.setColor(defaultColor);
//canvas.drawArc(smallOval, 185, 170, false, colorLinePaint);
canvas.drawCircle(250, 210, 180, colorLinePaint);
for (ColoredRange range: ranges) {
colorLinePaint.setColor(range.getColor());
//canvas.drawArc(smallOval, (float) (190 + range.getBegin()/ maxSpeed *160), (float) ((range.getEnd() - range.getBegin())/ maxSpeed *160), false, colorLinePaint);
//canvas.drawArc(smallOval, (float) (190 + range.getBegin()/ maxSpeed *160), (float) ((range.getEnd() - range.getBegin())/ maxSpeed *160), false, colorLinePaint);
//canvas.drawCircle((float) (190 + range.getBegin()/ maxSpeed *160), (float) ((range.getEnd() - range.getBegin())/ maxSpeed *160), 100, colorLinePaint);
//canvas.drawCircle((float)(300 + range.getBegin()/ maxSpeed *160), (float) ((range.getEnd() - range.getBegin())/ maxSpeed *160), 180, colorLinePaint);
}
}
private RectF getOval(Canvas canvas, float factor) {
RectF oval;
final int canvasWidth = canvas.getWidth() - getPaddingLeft() - getPaddingRight();
final int canvasHeight = canvas.getHeight() - getPaddingTop() - getPaddingBottom();
if (canvasHeight*2 >= canvasWidth) {
oval = new RectF(0, 0, canvasWidth*factor, canvasWidth*factor);
} else {
oval = new RectF(0, 0, canvasHeight*2*factor, canvasHeight*2*factor);
}
oval.offset((canvasWidth-oval.width())/2 + getPaddingLeft(), (canvasHeight*2-oval.height())/2 + getPaddingTop());
return oval;
}
Really got stuck on this. Please give me any hint or reference.
i created a View for you.. it may help.. just give a try... its only a basic view...i think it will give an idea..
package abbitfoot.likhil.customeprogressbar;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ProgressBar;
public class CustomeView extends View {
Paint red=new Paint();
Paint white=new Paint();
Paint bg=new Paint();
int radiusBg=200;
public CustomeView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
init();
}
private void init(){
red.setColor(Color.RED);
white.setColor(Color.WHITE);
bg.setColor(Color.rgb(0x99, 0x99, 0x99));
}
#Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
canvas.save();
canvas.drawCircle(getWidth()/2, getHeight()/2, radiusBg, bg);
Rect oval=new Rect(getWidth()/2-radiusBg+10, getHeight()/2-radiusBg+10,getWidth()/2+radiusBg-10,getHeight()/2+radiusBg-10 );
RectF rectF=new RectF(oval);
canvas.drawArc(rectF, 140,200,true, red);
canvas.drawArc(rectF, 340,60,true, white);
canvas.drawCircle(getWidth()/2, getHeight()/2, radiusBg-25, bg);
canvas.restore();
}
}
hope this will help you...and sorry this is not a rightmethod i think..
How to give hexagon shape to ImageView . Is it possible to do in same way ? If so then how. If this is not possible through this then how this could be achieved ?
<shape xmlns:android="http//schemas.android.com/apk/res/android"
android:shape="hexagon">
<solid android:color="#ffffffff" />
<size android:width="60dp"
android:height="40dp" />
</shape>
Screenshot
Here I can't do masking image because I can not detect which portion of bitmap I should crop to get hexagon shape bitmap. So I am looking for the answer to give hexagon shape to ImageView
Try this View. You might want to adjust it for your specific needs, but it draws a hexagon mask with a border on top of a view. The background resource goes below the mask.
The result:
The code:
HexagonMaskView.java
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Path;
import android.graphics.Region;
import android.util.AttributeSet;
import android.view.View;
public class HexagonMaskView extends View {
private Path hexagonPath;
private Path hexagonBorderPath;
private float radius;
private float width, height;
private int maskColor;
public HexagonMaskView(Context context) {
super(context);
init();
}
public HexagonMaskView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public HexagonMaskView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
hexagonPath = new Path();
hexagonBorderPath = new Path();
maskColor = 0xFF01FF77;
}
public void setRadius(float r) {
this.radius = r;
calculatePath();
}
public void setMaskColor(int color) {
this.maskColor = color;
invalidate();
}
private void calculatePath() {
float triangleHeight = (float) (Math.sqrt(3) * radius / 2);
float centerX = width/2;
float centerY = height/2;
hexagonPath.moveTo(centerX, centerY + radius);
hexagonPath.lineTo(centerX - triangleHeight, centerY + radius/2);
hexagonPath.lineTo(centerX - triangleHeight, centerY - radius/2);
hexagonPath.lineTo(centerX, centerY - radius);
hexagonPath.lineTo(centerX + triangleHeight, centerY - radius/2);
hexagonPath.lineTo(centerX + triangleHeight, centerY + radius/2);
hexagonPath.moveTo(centerX, centerY + radius);
float radiusBorder = radius - 5;
float triangleBorderHeight = (float) (Math.sqrt(3) * radiusBorder / 2);
hexagonBorderPath.moveTo(centerX, centerY + radiusBorder);
hexagonBorderPath.lineTo(centerX - triangleBorderHeight, centerY + radiusBorder/2);
hexagonBorderPath.lineTo(centerX - triangleBorderHeight, centerY - radiusBorder/2);
hexagonBorderPath.lineTo(centerX, centerY - radiusBorder);
hexagonBorderPath.lineTo(centerX + triangleBorderHeight, centerY - radiusBorder/2);
hexagonBorderPath.lineTo(centerX + triangleBorderHeight, centerY + radiusBorder/2);
hexagonBorderPath.moveTo(centerX, centerY + radiusBorder);
invalidate();
}
#Override
public void onDraw(Canvas c){
super.onDraw(c);
c.clipPath(hexagonBorderPath, Region.Op.DIFFERENCE);
c.drawColor(Color.WHITE);
c.save();
c.clipPath(hexagonPath, Region.Op.DIFFERENCE);
c.drawColor(maskColor);
c.save();
}
// getting the view size and default radius
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
width = MeasureSpec.getSize(widthMeasureSpec);
height = MeasureSpec.getSize(heightMeasureSpec);
radius = height / 2 - 10;
calculatePath();
}
}
Update 29.07.2016
A better way to only clip the source image without painting the whole view's background. Switched to an ImageView as a base class to benefit from the scaleType. I also did some code refactoring.
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.Region;
import android.util.AttributeSet;
import android.widget.ImageView;
public class HexagonMaskView extends ImageView {
private Path hexagonPath;
private Path hexagonBorderPath;
private Paint mBorderPaint;
public HexagonMaskView(Context context) {
super(context);
init();
}
public HexagonMaskView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public HexagonMaskView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
this.hexagonPath = new Path();
this.hexagonBorderPath = new Path();
this.mBorderPaint = new Paint();
this.mBorderPaint.setColor(Color.WHITE);
this.mBorderPaint.setStrokeCap(Paint.Cap.ROUND);
this.mBorderPaint.setStrokeWidth(50f);
this.mBorderPaint.setStyle(Paint.Style.STROKE);
}
public void setRadius(float radius) {
calculatePath(radius);
}
public void setBorderColor(int color) {
this.mBorderPaint.setColor(color);
invalidate();
}
private void calculatePath(float radius) {
float halfRadius = radius / 2f;
float triangleHeight = (float) (Math.sqrt(3.0) * halfRadius);
float centerX = getMeasuredWidth() / 2f;
float centerY = getMeasuredHeight() / 2f;
this.hexagonPath.reset();
this.hexagonPath.moveTo(centerX, centerY + radius);
this.hexagonPath.lineTo(centerX - triangleHeight, centerY + halfRadius);
this.hexagonPath.lineTo(centerX - triangleHeight, centerY - halfRadius);
this.hexagonPath.lineTo(centerX, centerY - radius);
this.hexagonPath.lineTo(centerX + triangleHeight, centerY - halfRadius);
this.hexagonPath.lineTo(centerX + triangleHeight, centerY + halfRadius);
this.hexagonPath.close();
float radiusBorder = radius - 5f;
float halfRadiusBorder = radiusBorder / 2f;
float triangleBorderHeight = (float) (Math.sqrt(3.0) * halfRadiusBorder);
this.hexagonBorderPath.reset();
this.hexagonBorderPath.moveTo(centerX, centerY + radiusBorder);
this.hexagonBorderPath.lineTo(centerX - triangleBorderHeight, centerY + halfRadiusBorder);
this.hexagonBorderPath.lineTo(centerX - triangleBorderHeight, centerY - halfRadiusBorder);
this.hexagonBorderPath.lineTo(centerX, centerY - radiusBorder);
this.hexagonBorderPath.lineTo(centerX + triangleBorderHeight, centerY - halfRadiusBorder);
this.hexagonBorderPath.lineTo(centerX + triangleBorderHeight, centerY + halfRadiusBorder);
this.hexagonBorderPath.close();
invalidate();
}
#Override
public void onDraw(Canvas c) {
c.drawPath(hexagonBorderPath, mBorderPaint);
c.clipPath(hexagonPath, Region.Op.INTERSECT);
c.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
super.onDraw(c);
}
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
setMeasuredDimension(width, height);
calculatePath(Math.min(width / 2f, height / 2f) - 10f);
}
}
Example layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:background="#android:color/holo_green_dark">
<com.scelus.hexagonmaskimproved.HexagonMaskView
android:id="#+id/image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/bear"
android:background="#android:color/holo_green_light"/>
</RelativeLayout>
Here is my working code for this, it supports shadows to:
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.util.AttributeSet;
import android.widget.ImageView;
public class HexagonImageView extends ImageView {
private Path hexagonPath;
private Path hexagonBorderPath;
private float radius;
private Bitmap image;
private int viewWidth;
private int viewHeight;
private Paint paint;
private BitmapShader shader;
private Paint paintBorder;
private int borderWidth = 4;
public HexagonImageView(Context context) {
super(context);
setup();
}
public HexagonImageView(Context context, AttributeSet attrs) {
super(context, attrs);
setup();
}
public HexagonImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setup();
}
private void setup() {
paint = new Paint();
paint.setAntiAlias(true);
paintBorder = new Paint();
setBorderColor(Color.WHITE);
paintBorder.setAntiAlias(true);
this.setLayerType(LAYER_TYPE_SOFTWARE, paintBorder);
paintBorder.setShadowLayer(4.0f, 1.0f, 1.0f, Color.BLACK);
hexagonPath = new Path();
hexagonBorderPath = new Path();
}
public void setRadius(float r) {
this.radius = r;
calculatePath();
}
public void setBorderWidth(int borderWidth) {
this.borderWidth = borderWidth;
this.invalidate();
}
public void setBorderColor(int borderColor) {
if (paintBorder != null)
paintBorder.setColor(borderColor);
this.invalidate();
}
private void calculatePath() {
float triangleHeight = (float) (Math.sqrt(3) * radius / 2);
float centerX = viewWidth/2;
float centerY = viewHeight/2;
hexagonBorderPath.moveTo(centerX, centerY + radius);
hexagonBorderPath.lineTo(centerX - triangleHeight, centerY + radius/2);
hexagonBorderPath.lineTo(centerX - triangleHeight, centerY - radius/2);
hexagonBorderPath.lineTo(centerX, centerY - radius);
hexagonBorderPath.lineTo(centerX + triangleHeight, centerY - radius/2);
hexagonBorderPath.lineTo(centerX + triangleHeight, centerY + radius/2);
hexagonBorderPath.moveTo(centerX, centerY + radius);
float radiusBorder = radius - borderWidth;
float triangleBorderHeight = (float) (Math.sqrt(3) * radiusBorder / 2);
hexagonPath.moveTo(centerX, centerY + radiusBorder);
hexagonPath.lineTo(centerX - triangleBorderHeight, centerY + radiusBorder/2);
hexagonPath.lineTo(centerX - triangleBorderHeight, centerY - radiusBorder/2);
hexagonPath.lineTo(centerX, centerY - radiusBorder);
hexagonPath.lineTo(centerX + triangleBorderHeight, centerY - radiusBorder/2);
hexagonPath.lineTo(centerX + triangleBorderHeight, centerY + radiusBorder/2);
hexagonPath.moveTo(centerX, centerY + radiusBorder);
invalidate();
}
private void loadBitmap() {
BitmapDrawable bitmapDrawable = (BitmapDrawable) this.getDrawable();
if (bitmapDrawable != null)
image = bitmapDrawable.getBitmap();
}
#SuppressLint("DrawAllocation")
#Override
public void onDraw(Canvas canvas){
super.onDraw(canvas);
loadBitmap();
// init shader
if (image != null) {
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
shader = new BitmapShader(Bitmap.createScaledBitmap(image, canvas.getWidth(), canvas.getHeight(), false), Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
paint.setShader(shader);
canvas.drawPath(hexagonBorderPath, paintBorder);
canvas.drawPath(hexagonPath, paint);
}
}
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = measureWidth(widthMeasureSpec);
int height = measureHeight(heightMeasureSpec, widthMeasureSpec);
viewWidth = width - (borderWidth * 2);
viewHeight = height - (borderWidth * 2);
radius = height / 2 - borderWidth;
calculatePath();
setMeasuredDimension(width, height);
}
private int measureWidth(int measureSpec) {
int result = 0;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if (specMode == MeasureSpec.EXACTLY) {
result = specSize;
}
else {
result = viewWidth;
}
return result;
}
private int measureHeight(int measureSpecHeight, int measureSpecWidth) {
int result = 0;
int specMode = MeasureSpec.getMode(measureSpecHeight);
int specSize = MeasureSpec.getSize(measureSpecHeight);
if (specMode == MeasureSpec.EXACTLY) {
result = specSize;
}
else {
result = viewHeight;
}
return (result + 2);
}
}
There are a couple things you can try:
You might want to try drawing a 9patch in top of your image.
There's also this short tuto by Romain Guy : http://www.curious-creature.org/2012/12/11/android-recipe-1-image-with-rounded-corners/
BitmapShader shader;
shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setShader(shader);
RectF rect = new RectF(0.0f, 0.0f, width, height);
// rect contains the bounds of the shape
// radius is the radius in pixels of the rounded corners
// paint contains the shader that will texture the shape
canvas.drawRoundRect(rect, radius, radius, paint);
Instead of using drawRoundRect() method of canvas, you may try using drawPath() to get the desired shape.
Hope this puts you on the right direction.
See this example which is creating triangle so you can get logic from it :)
http://looksok.wordpress.com/2013/08/24/android-triangle-arrow-defined-as-an-xml-shape/
Another solution I found but not tested so try this also
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView tv = (TextView) findViewById(R.id.text);
Path path = new Path();
float stdW = 100;
float stdH = 100;
float w3 = stdW / 3;
float h2 = stdH / 2;
path.moveTo(0, h2);
h2 -= 6 / 2;
path.rLineTo(w3, -h2); path.rLineTo(w3, 0); path.rLineTo(w3, h2);
path.rLineTo(-w3, h2); path.rLineTo(-w3, 0); path.rLineTo(-w3, -h2);
Shape s = new PathShape(path, stdW, stdH);
ShapeDrawable d = new ShapeDrawable(s);
Paint p = d.getPaint();
p.setColor(0xffeeeeee);
p.setStyle(Style.STROKE);
p.setStrokeWidth(6);
tv.setBackgroundDrawable(d);
}
Source: Google group
Third solution - This might be useful library
PathDrawable is a Drawable that draws simple shapes using Path object.
Its Late to relpy.. But Hope it will help someone...
public Bitmap getHexagonShape(Bitmap scaleBitmapImage) {
// TODO Auto-generated method stub
int targetWidth = 200;
int targetHeight =200;
Bitmap targetBitmap = Bitmap.createBitmap(targetWidth,
targetHeight,Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(targetBitmap);
Path path = new Path();
float stdW = 200;
float stdH = 200;
float w3 =stdW / 2;
float h2 = stdH / 2;
float radius=stdH/2-10;
float triangleHeight = (float) (Math.sqrt(3) * radius / 2);
float centerX = stdW/2;
float centerY = stdH/2;
path.moveTo(centerX, centerY + radius);
path.lineTo(centerX - triangleHeight, centerY + radius/2);
path.lineTo(centerX - triangleHeight, centerY - radius/2);
path.lineTo(centerX, centerY - radius);
path.lineTo(centerX + triangleHeight, centerY - radius/2);
path.lineTo(centerX + triangleHeight, centerY + radius/2);
path.moveTo(centerX, centerY + radius);
canvas.clipPath(path);
Bitmap sourceBitmap = scaleBitmapImage;
canvas.drawBitmap(sourceBitmap,
new Rect(0, 0, sourceBitmap.getWidth(),
sourceBitmap.getHeight()),
new Rect(0, 0, targetWidth,
targetHeight), null);
return targetBitmap;
}
public static Bitmap drawableToBitmap (Drawable drawable) {
if (drawable instanceof BitmapDrawable) {
return ((BitmapDrawable)drawable).getBitmap();
}
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
Call this where you want to use
Drawable drawable = getResources().getDrawable( R.drawable.placeholder );
Bitmap b=getHexagonShape(drawableToBitmap(drawable));
img=(ImageView)findViewById(R.id.imageView);
img.setImageBitmap(b);
The function below reads your image as input bitmap and returns a bitmap which is hexagon in shape
public Bitmap getHexagonShape(Bitmap scaleBitmapImage) {
// TODO Auto-generated method stub
int targetWidth = 600;
int targetHeight = 600;
Bitmap targetBitmap = Bitmap.createBitmap(targetWidth,
targetHeight,Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(targetBitmap);
Path path = new Path();
float stdW = 300;
float stdH = 300;
float w3 =stdW / 2;
float h2 = stdH / 2;
path.moveTo(0, (float) (h2*Math.sqrt(3)/2));
path.rLineTo(w3/2, -(float) (h2*Math.sqrt(3)/2)); path.rLineTo(w3, 0); path.rLineTo(w3/2, (float) (h2*Math.sqrt(3)/2));
path.rLineTo(-w3/2, (float) (h2*Math.sqrt(3)/2)); path.rLineTo(-w3, 0); path.rLineTo(-w3/2, -(float) (h2*Math.sqrt(3)/2));
canvas.clipPath(path);
Bitmap sourceBitmap = scaleBitmapImage;
canvas.drawBitmap(sourceBitmap,
new Rect(0, 0, sourceBitmap.getWidth(),
sourceBitmap.getHeight()),
new Rect(0, 0, targetWidth,
targetHeight), null);
return targetBitmap;
}
I don't know if the OP got the answer he was looking for, but here goes.
I've create a custom view, that extends ImageView, that will do the job for you a bit better.
The answer here just creates a maks inside the ImageView and forces you to set the picture as the background
My view lets you set the image like a standard bitmap, it handles CenterCrop and scaling of the image.
It actually sets the mask outside instead, and with the same border plus drop shadow.
And if that not enough, you can easily create custom shapes to render, just be extending the RenderShape-class. (4 shapes are included in the library: Circle, Triangle, Hexagon and Octagon)
Have a look at my github
Cheers
I've solved it using this code:
private Bitmap getHexagoneCroppedBitmap(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(), Config.ARGB_8888);
Canvas canvas = new Canvas(output);
Paint paint = new Paint();
final Rect rect = new Rect(0, 0, finalBitmap.getWidth(),
finalBitmap.getHeight());
Point point1_draw = new Point(75, 0);
Point point2_draw = new Point(0, 50);
Point point3_draw = new Point(0, 100);
Point point4_draw = new Point(75, 150);
Point point5_draw = new Point(150, 100);
Point point6_draw = new Point(150, 50);
Path path = new Path();
path.moveTo(point1_draw.x, point1_draw.y);
path.lineTo(point2_draw.x, point2_draw.y);
path.lineTo(point3_draw.x, point3_draw.y);
path.lineTo(point4_draw.x, point4_draw.y);
path.lineTo(point5_draw.x, point5_draw.y);
path.lineTo(point6_draw.x, point6_draw.y);
path.close();
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(Color.parseColor("#BAB399"));
canvas.drawPath(path, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(finalBitmap, rect, rect, paint);
return output;
}
You can use the Android Shape ImageView by siamed.
https://github.com/siyamed/android-shape-imageview
<com.github.siyamed.shapeimageview.HexagonImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="8dp"
android:src="#drawable/neo"
app:siBorderWidth="8dp"
app:siBorderColor="#color/darkgray"/>
Please read the documentation on github, lots of options are available.