问题
I'm going on with image view to pic from gallery or take picture from camera after all process we view the image in a square by default can we change the view to circle shape by default using SDK in Android.
Is there any possibility with out cropping the image only by using SDK.
If anyone have idea about this please help me guys.
回答1:
There are a lot of library and post on this topic. Here are some:
- CircularImageView
- CircleImageView
- Stackoverflow post 1
- Stackoverflow post 2
- Stackoverflow post 3
- Stackoverflow post 4 //this is using xml
回答2:
Use this:
public class RoundedImageView extends ImageView {
private Paint objPaint = new Paint();
public RoundedImageView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public RoundedImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public RoundedImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onDraw(Canvas canvas) {
Drawable drawable = getDrawable();
if (drawable == null) {
return;
}
if (getWidth() == 0 || getHeight() == 0) {
return;
}
Bitmap b = ((BitmapDrawable) drawable).getBitmap();
Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true);
int w = getWidth(), h = getHeight();
Log.i("TAG", "Bitmap Width:" + w);
Bitmap roundBitmap = getCroppedBitmap(bitmap, w);
objPaint.setAntiAlias(true);
objPaint.setDither(true);
canvas.drawBitmap(roundBitmap, 0, 0, objPaint);
}
public static Bitmap getCroppedBitmap(Bitmap bmp, int radius) {
Bitmap sbmp;
if (bmp.getWidth() != radius || bmp.getHeight() != radius)
sbmp = Bitmap.createScaledBitmap(bmp, radius, radius, false);
else
sbmp = bmp;
Bitmap output = Bitmap.createBitmap(sbmp.getWidth(), sbmp.getHeight(),
Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xffa19774;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, sbmp.getWidth(), sbmp.getHeight());
paint.setAntiAlias(true);
paint.setFilterBitmap(true);
paint.setDither(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(Color.parseColor("#BAB399"));
canvas.drawCircle(sbmp.getWidth() / 2 + 0.7f,
sbmp.getHeight() / 2 + 0.7f, sbmp.getWidth() / 2 + 0.1f, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(sbmp, rect, rect, paint);
return output;
}
}
Now For Declaring ImageView in your xml:
<yourpackage.RoundedImageView
android:id="@+id/iv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/bg" />
回答3:
Try below code:
Just paste below code as a class:
@SuppressWarnings("UnusedDeclaration")
public class RoundedImageView extends ImageView {
public static final String TAG = "RoundedImageView";
public static final int DEFAULT_RADIUS = 0;
public static final int DEFAULT_BORDER_WIDTH = 0;
private static final ScaleType[] SCALE_TYPES = {
ScaleType.MATRIX,
ScaleType.FIT_XY,
ScaleType.FIT_START,
ScaleType.FIT_CENTER,
ScaleType.FIT_END,
ScaleType.CENTER,
ScaleType.CENTER_CROP,
ScaleType.CENTER_INSIDE
};
private int mCornerRadius = DEFAULT_RADIUS;
private int mBorderWidth = DEFAULT_BORDER_WIDTH;
private ColorStateList mBorderColor =
ColorStateList.valueOf(RoundedDrawable.DEFAULT_BORDER_COLOR);
private boolean mOval = false;
private boolean mRoundBackground = false;
private int mResource;
private Drawable mDrawable;
private Drawable mBackgroundDrawable;
private ScaleType mScaleType;
public RoundedImageView(Context context) {
super(context);
}
public RoundedImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public RoundedImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RoundedImageView, defStyle, 0);
int index = a.getInt(R.styleable.RoundedImageView_android_scaleType, 1);
if (index >= 0) {
setScaleType(SCALE_TYPES[index]);
} else {
// default scaletype to FIT_CENTER
setScaleType(ScaleType.FIT_CENTER);
}
mCornerRadius = a.getDimensionPixelSize(R.styleable.RoundedImageView_corner_radius, 360);
mBorderWidth = a.getDimensionPixelSize(R.styleable.RoundedImageView_border_width,2);
// don't allow negative values for radius and border
if (mCornerRadius < 0) {
mCornerRadius = DEFAULT_RADIUS;
}
if (mBorderWidth < 0) {
mBorderWidth = DEFAULT_BORDER_WIDTH;
}
mBorderColor = a.getColorStateList(R.styleable.RoundedImageView_border_color);
if (mBorderColor == null) {
mBorderColor = ColorStateList.valueOf(R.color.blue);
}
mRoundBackground = a.getBoolean(R.styleable.RoundedImageView_round_background, false);
mOval = a.getBoolean(R.styleable.RoundedImageView_is_oval, false);
updateDrawableAttrs();
updateBackgroundDrawableAttrs();
a.recycle();
}
@Override
protected void drawableStateChanged() {
super.drawableStateChanged();
invalidate();
}
/**
* Return the current scale type in use by this ImageView.
*
* @attr ref android.R.styleable#ImageView_scaleType
* @see android.widget.ImageView.ScaleType
*/
@Override
public ScaleType getScaleType() {
return mScaleType;
}
/**
* Controls how the image should be resized or moved to match the size
* of this ImageView.
*
* @param scaleType The desired scaling mode.
* @attr ref android.R.styleable#ImageView_scaleType
*/
@Override
public void setScaleType(ScaleType scaleType) {
if (scaleType == null) {
throw new NullPointerException();
}
if (mScaleType != scaleType) {
mScaleType = scaleType;
switch (scaleType) {
case CENTER:
case CENTER_CROP:
case CENTER_INSIDE:
case FIT_CENTER:
case FIT_START:
case FIT_END:
case FIT_XY:
super.setScaleType(ScaleType.FIT_XY);
break;
default:
super.setScaleType(scaleType);
break;
}
updateDrawableAttrs();
updateBackgroundDrawableAttrs();
invalidate();
}
}
@Override
public void setImageDrawable(Drawable drawable) {
mResource = 0;
mDrawable = RoundedDrawable.fromDrawable(drawable);
updateDrawableAttrs();
super.setImageDrawable(mDrawable);
}
@Override
public void setImageBitmap(Bitmap bm) {
mResource = 0;
mDrawable = RoundedDrawable.fromBitmap(bm);
updateDrawableAttrs();
super.setImageDrawable(mDrawable);
}
@Override
public void setImageResource(int resId) {
if (mResource != resId) {
mResource = resId;
mDrawable = resolveResource();
updateDrawableAttrs();
super.setImageDrawable(mDrawable);
}
}
@Override public void setImageURI(Uri uri) {
super.setImageURI(uri);
setImageDrawable(getDrawable());
}
private Drawable resolveResource() {
Resources rsrc = getResources();
if (rsrc == null) {
return null;
}
Drawable d = null;
if (mResource != 0) {
try {
d = rsrc.getDrawable(mResource);
} catch (Exception e) {
Log.w(TAG, "Unable to find resource: " + mResource, e);
// Don't try again.
mResource = 0;
}
}
return RoundedDrawable.fromDrawable(d);
}
@Override
public void setBackground(Drawable background) {
setBackgroundDrawable(background);
}
private void updateDrawableAttrs() {
updateAttrs(mDrawable, false);
}
private void updateBackgroundDrawableAttrs() {
updateAttrs(mBackgroundDrawable, true);
}
private void updateAttrs(Drawable drawable, boolean background) {
if (drawable == null) {
return;
}
if (drawable instanceof RoundedDrawable) {
((RoundedDrawable) drawable)
.setScaleType(mScaleType)
.setCornerRadius(background && !mRoundBackground ? 0 : mCornerRadius)
.setBorderWidth(background && !mRoundBackground ? 0 : mBorderWidth)
.setBorderColors(mBorderColor)
.setOval(mOval);
} else if (drawable instanceof LayerDrawable) {
// loop through layers to and set drawable attrs
LayerDrawable ld = ((LayerDrawable) drawable);
int layers = ld.getNumberOfLayers();
for (int i = 0; i < layers; i++) {
updateAttrs(ld.getDrawable(i), background);
}
}
}
@Override
@Deprecated
public void setBackgroundDrawable(Drawable background) {
mBackgroundDrawable = RoundedDrawable.fromDrawable(background);
updateBackgroundDrawableAttrs();
super.setBackgroundDrawable(mBackgroundDrawable);
}
public int getCornerRadius() {
return mCornerRadius;
}
public void setCornerRadius(int radius) {
if (mCornerRadius == radius) {
return;
}
mCornerRadius = radius;
updateDrawableAttrs();
updateBackgroundDrawableAttrs();
}
public int getBorderWidth() {
return mBorderWidth;
}
public void setBorderWidth(int width) {
if (mBorderWidth == width) {
return;
}
mBorderWidth = width;
updateDrawableAttrs();
updateBackgroundDrawableAttrs();
invalidate();
}
public int getBorderColor() {
return mBorderColor.getDefaultColor();
}
public void setBorderColor(int color) {
setBorderColors(ColorStateList.valueOf(color));
}
public ColorStateList getBorderColors() {
return mBorderColor;
}
public void setBorderColors(ColorStateList colors) {
if (mBorderColor.equals(colors)) {
return;
}
mBorderColor =
(colors != null) ? colors : ColorStateList.valueOf(RoundedDrawable.DEFAULT_BORDER_COLOR);
updateDrawableAttrs();
updateBackgroundDrawableAttrs();
if (mBorderWidth > 0) {
invalidate();
}
}
public boolean isOval() {
return mOval;
}
public void setOval(boolean oval) {
mOval = oval;
updateDrawableAttrs();
updateBackgroundDrawableAttrs();
invalidate();
}
public boolean isRoundBackground() {
return mRoundBackground;
}
public void setRoundBackground(boolean roundBackground) {
if (mRoundBackground == roundBackground) {
return;
}
mRoundBackground = roundBackground;
updateBackgroundDrawableAttrs();
invalidate();
}
}
Paste below code as a class:
@SuppressWarnings("UnusedDeclaration")
public class RoundedDrawable extends Drawable {
public static final String TAG = "RoundedDrawable";
public static final int DEFAULT_BORDER_COLOR = Color.BLACK;
private final RectF mBounds = new RectF();
private final RectF mDrawableRect = new RectF();
private final RectF mBitmapRect = new RectF();
private final BitmapShader mBitmapShader;
private final Paint mBitmapPaint;
private final int mBitmapWidth;
private final int mBitmapHeight;
private final RectF mBorderRect = new RectF();
private final Paint mBorderPaint;
private final Matrix mShaderMatrix = new Matrix();
private float mCornerRadius = 0;
private boolean mOval = false;
private float mBorderWidth = 0;
private ColorStateList mBorderColor = ColorStateList.valueOf(DEFAULT_BORDER_COLOR);
private ScaleType mScaleType = ScaleType.FIT_CENTER;
public RoundedDrawable(Bitmap bitmap) {
mBitmapWidth = bitmap.getWidth();
mBitmapHeight = bitmap.getHeight();
mBitmapRect.set(0, 0, mBitmapWidth, mBitmapHeight);
mBitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
mBitmapShader.setLocalMatrix(mShaderMatrix);
mBitmapPaint = new Paint();
mBitmapPaint.setStyle(Paint.Style.FILL);
mBitmapPaint.setAntiAlias(true);
mBitmapPaint.setShader(mBitmapShader);
mBorderPaint = new Paint();
mBorderPaint.setStyle(Paint.Style.STROKE);
mBorderPaint.setAntiAlias(true);
mBorderPaint.setColor(mBorderColor.getColorForState(getState(), DEFAULT_BORDER_COLOR));
mBorderPaint.setStrokeWidth(mBorderWidth);
}
public static RoundedDrawable fromBitmap(Bitmap bitmap) {
if (bitmap != null) {
return new RoundedDrawable(bitmap);
} else {
return null;
}
}
public static Drawable fromDrawable(Drawable drawable) {
if (drawable != null) {
if (drawable instanceof RoundedDrawable) {
// just return if it's already a RoundedDrawable
return drawable;
} else if (drawable instanceof LayerDrawable) {
LayerDrawable ld = (LayerDrawable) drawable;
int num = ld.getNumberOfLayers();
// loop through layers to and change to RoundedDrawables if possible
for (int i = 0; i < num; i++) {
Drawable d = ld.getDrawable(i);
ld.setDrawableByLayerId(ld.getId(i), fromDrawable(d));
}
return ld;
}
// try to get a bitmap from the drawable and
Bitmap bm = drawableToBitmap(drawable);
if (bm != null) {
return new RoundedDrawable(bm);
} else {
Log.w(TAG, "Failed to create bitmap from drawable!");
}
}
return drawable;
}
public static Bitmap drawableToBitmap(Drawable drawable) {
if (drawable instanceof BitmapDrawable) {
return ((BitmapDrawable) drawable).getBitmap();
}
Bitmap bitmap;
int width = Math.max(drawable.getIntrinsicWidth(), 1);
int height = Math.max(drawable.getIntrinsicHeight(), 1);
try {
bitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
} catch (Exception e) {
e.printStackTrace();
bitmap = null;
}
return bitmap;
}
@Override
public boolean isStateful() {
return mBorderColor.isStateful();
}
@Override
protected boolean onStateChange(int[] state) {
int newColor = mBorderColor.getColorForState(state, 0);
if (mBorderPaint.getColor() != newColor) {
mBorderPaint.setColor(newColor);
return true;
} else {
return super.onStateChange(state);
}
}
private void updateShaderMatrix() {
float scale;
float dx;
float dy;
switch (mScaleType) {
case CENTER:
mBorderRect.set(mBounds);
mBorderRect.inset((mBorderWidth) / 2, (mBorderWidth) / 2);
mShaderMatrix.set(null);
mShaderMatrix.setTranslate((int) ((mBorderRect.width() - mBitmapWidth) * 0.5f + 0.5f),
(int) ((mBorderRect.height() - mBitmapHeight) * 0.5f + 0.5f));
break;
case CENTER_CROP:
mBorderRect.set(mBounds);
mBorderRect.inset((mBorderWidth) / 2, (mBorderWidth) / 2);
mShaderMatrix.set(null);
dx = 0;
dy = 0;
if (mBitmapWidth * mBorderRect.height() > mBorderRect.width() * mBitmapHeight) {
scale = mBorderRect.height() / (float) mBitmapHeight;
dx = (mBorderRect.width() - mBitmapWidth * scale) * 0.5f;
} else {
scale = mBorderRect.width() / (float) mBitmapWidth;
dy = (mBorderRect.height() - mBitmapHeight * scale) * 0.5f;
}
mShaderMatrix.setScale(scale, scale);
mShaderMatrix.postTranslate((int) (dx + 0.5f) + mBorderWidth,
(int) (dy + 0.5f) + mBorderWidth);
break;
case CENTER_INSIDE:
mShaderMatrix.set(null);
if (mBitmapWidth <= mBounds.width() && mBitmapHeight <= mBounds.height()) {
scale = 1.0f;
} else {
scale = Math.min(mBounds.width() / (float) mBitmapWidth,
mBounds.height() / (float) mBitmapHeight);
}
dx = (int) ((mBounds.width() - mBitmapWidth * scale) * 0.5f + 0.5f);
dy = (int) ((mBounds.height() - mBitmapHeight * scale) * 0.5f + 0.5f);
mShaderMatrix.setScale(scale, scale);
mShaderMatrix.postTranslate(dx, dy);
mBorderRect.set(mBitmapRect);
mShaderMatrix.mapRect(mBorderRect);
mBorderRect.inset((mBorderWidth) / 2, (mBorderWidth) / 2);
mShaderMatrix.setRectToRect(mBitmapRect, mBorderRect, Matrix.ScaleToFit.FILL);
break;
default:
case FIT_CENTER:
mBorderRect.set(mBitmapRect);
mShaderMatrix.setRectToRect(mBitmapRect, mBounds, Matrix.ScaleToFit.CENTER);
mShaderMatrix.mapRect(mBorderRect);
mBorderRect.inset((mBorderWidth) / 2, (mBorderWidth) / 2);
mShaderMatrix.setRectToRect(mBitmapRect, mBorderRect, Matrix.ScaleToFit.FILL);
break;
case FIT_END:
mBorderRect.set(mBitmapRect);
mShaderMatrix.setRectToRect(mBitmapRect, mBounds, Matrix.ScaleToFit.END);
mShaderMatrix.mapRect(mBorderRect);
mBorderRect.inset((mBorderWidth) / 2, (mBorderWidth) / 2);
mShaderMatrix.setRectToRect(mBitmapRect, mBorderRect, Matrix.ScaleToFit.FILL);
break;
case FIT_START:
mBorderRect.set(mBitmapRect);
mShaderMatrix.setRectToRect(mBitmapRect, mBounds, Matrix.ScaleToFit.START);
mShaderMatrix.mapRect(mBorderRect);
mBorderRect.inset((mBorderWidth) / 2, (mBorderWidth) / 2);
mShaderMatrix.setRectToRect(mBitmapRect, mBorderRect, Matrix.ScaleToFit.FILL);
break;
case FIT_XY:
mBorderRect.set(mBounds);
mBorderRect.inset((mBorderWidth) / 2, (mBorderWidth) / 2);
mShaderMatrix.set(null);
mShaderMatrix.setRectToRect(mBitmapRect, mBorderRect, Matrix.ScaleToFit.FILL);
break;
}
mDrawableRect.set(mBorderRect);
mBitmapShader.setLocalMatrix(mShaderMatrix);
}
@Override
protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds);
mBounds.set(bounds);
updateShaderMatrix();
}
@Override
public void draw(Canvas canvas) {
if (mOval) {
if (mBorderWidth > 0) {
canvas.drawOval(mDrawableRect, mBitmapPaint);
canvas.drawOval(mBorderRect, mBorderPaint);
} else {
canvas.drawOval(mDrawableRect, mBitmapPaint);
}
} else {
if (mBorderWidth > 0) {
canvas.drawRoundRect(mDrawableRect, Math.max(mCornerRadius, 0),
Math.max(mCornerRadius, 0), mBitmapPaint);
canvas.drawRoundRect(mBorderRect, mCornerRadius, mCornerRadius, mBorderPaint);
} else {
canvas.drawRoundRect(mDrawableRect, mCornerRadius, mCornerRadius, mBitmapPaint);
}
}
}
@Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
@Override
public void setAlpha(int alpha) {
mBitmapPaint.setAlpha(alpha);
invalidateSelf();
}
@Override
public void setColorFilter(ColorFilter cf) {
mBitmapPaint.setColorFilter(cf);
invalidateSelf();
}
@Override public void setDither(boolean dither) {
mBitmapPaint.setDither(dither);
invalidateSelf();
}
@Override public void setFilterBitmap(boolean filter) {
mBitmapPaint.setFilterBitmap(filter);
invalidateSelf();
}
@Override
public int getIntrinsicWidth() {
return mBitmapWidth;
}
@Override
public int getIntrinsicHeight() {
return mBitmapHeight;
}
public float getCornerRadius() {
return mCornerRadius;
}
public RoundedDrawable setCornerRadius(float radius) {
mCornerRadius = radius;
return this;
}
public float getBorderWidth() {
return mBorderWidth;
}
public RoundedDrawable setBorderWidth(int width) {
mBorderWidth = width;
mBorderPaint.setStrokeWidth(mBorderWidth);
return this;
}
public int getBorderColor() {
return mBorderColor.getDefaultColor();
}
public RoundedDrawable setBorderColor(int color) {
return setBorderColors(ColorStateList.valueOf(color));
}
public ColorStateList getBorderColors() {
return mBorderColor;
}
public RoundedDrawable setBorderColors(ColorStateList colors) {
mBorderColor = colors != null ? colors : ColorStateList.valueOf(0);
mBorderPaint.setColor(mBorderColor.getColorForState(getState(), DEFAULT_BORDER_COLOR));
return this;
}
public boolean isOval() {
return mOval;
}
public RoundedDrawable setOval(boolean oval) {
mOval = oval;
return this;
}
public ScaleType getScaleType() {
return mScaleType;
}
public RoundedDrawable setScaleType(ScaleType scaleType) {
if (scaleType == null) {
scaleType = ScaleType.FIT_XY;
}
if (mScaleType != scaleType) {
mScaleType = scaleType;
updateShaderMatrix();
}
return this;
}
public Bitmap toBitmap() {
return drawableToBitmap(this);
}
}
//Your ImageView in your xml:
Do not forget to declare below lines :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res/YOUR MAIN PACKAGE NAME"
<com.ijoomer.customviews.RoundedImageView
android:id="@+id/imgArticleImage"
android:layout_width="140dp"
android:layout_height="140dp"
android:layout_centerInParent="true"
android:adjustViewBounds="true"
android:scaleType="fitXY"
app:is_oval="false"
app:corner_radius="360dp"
app:border_color="@color/blue"/>
//Then in your class file:
private RoundedImageView imgArticleImage;
imgArticleImage = (RoundedImageView)findViewById(R.id.imgArticleImage);
imgArticleImage.setImageBitmap(YOUR SELECTED BITMAP);
Also, put stylable in attrs.xml:
<declare-styleable name="RoundedImageView">
<attr name="corner_radius" format="dimension" />
<attr name="border_width" format="dimension" />
<attr name="border_color" format="color" />
<attr name="round_background" format="boolean" />
<attr name="is_oval" format="boolean" />
<attr name="android:scaleType" />
</declare-styleable>
来源:https://stackoverflow.com/questions/24955202/how-to-show-image-view-in-circle