学习笔记之——Android中的Picasso实现圆形头像、圆角图片工具类

编程入门 行业动态 更新时间:2024-10-07 01:31:27

学习笔记之——Android中的Picasso实现<a href=https://www.elefans.com/category/jswz/34/1769013.html style=圆形头像、圆角图片工具类"/>

学习笔记之——Android中的Picasso实现圆形头像、圆角图片工具类

Android中的Picasso实现圆形头像、圆角图片工具类

一.圆形头像工具类


/*** @author LXL1123* 配合picaso 圆形头像 工具类*/
public class CircleTransform implements Transformation {@Overridepublic Bitmap transform(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;}@Overridepublic String key() {return "circle";}
}

使用:

Picasso.with(getContext())
.load(saveAvatar)
.transform(new CircleTransform())
.into(img_avatar);

二.圆角图片工具类


Corner.java

@Retention(RetentionPolicy.SOURCE)
@IntDef({Corner.TOP_LEFT, Corner.TOP_RIGHT,Corner.BOTTOM_LEFT, Corner.BOTTOM_RIGHT
})
public @interface Corner {int TOP_LEFT = 0;int TOP_RIGHT = 1;int BOTTOM_RIGHT = 2;int BOTTOM_LEFT = 3;
}
RoundedDrawable.java

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 Bitmap mBitmap;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 final RectF mSquareCornersRect = new RectF();private Shader.TileMode mTileModeX = Shader.TileMode.CLAMP;private Shader.TileMode mTileModeY = Shader.TileMode.CLAMP;private boolean mRebuildShader = true;// [ topLeft, topRight, bottomLeft, bottomRight ]private float mCornerRadius = 0f;private final boolean[] mCornersRounded = new boolean[] { true, true, true, true };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) {mBitmap = bitmap;mBitmapWidth = bitmap.getWidth();mBitmapHeight = bitmap.getHeight();mBitmapRect.set(0, 0, mBitmapWidth, mBitmapHeight);mBitmapPaint = new Paint();mBitmapPaint.setStyle(Paint.Style.FILL);mBitmapPaint.setAntiAlias(true);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 RoundedDrawablereturn drawable;} else if (drawable instanceof LayerDrawable) {LayerDrawable ld = (LayerDrawable) drawable;int num = ld.getNumberOfLayers();// loop through layers to and change to RoundedDrawables if possiblefor (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 andBitmap bm = drawableToBitmap(drawable);if (bm != null) {return new RoundedDrawable(bm);}}return drawable;}public static Bitmap drawableToBitmap(Drawable drawable) {if (drawable instanceof BitmapDrawable) {return ((BitmapDrawable) drawable).getBitmap();}Bitmap bitmap;int width = Math.max(drawable.getIntrinsicWidth(), 2);int height = Math.max(drawable.getIntrinsicHeight(), 2);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();Log.w(TAG, "Failed to create bitmap from drawable!");bitmap = null;}return bitmap;}public Bitmap getSourceBitmap() {return mBitmap;}@Overridepublic boolean isStateful() {return mBorderColor.isStateful();}@Overrideprotected 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.reset();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.reset();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 / 2,(int) (dy + 0.5f) + mBorderWidth / 2);break;case CENTER_INSIDE:mShaderMatrix.reset();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.reset();mShaderMatrix.setRectToRect(mBitmapRect, mBorderRect, Matrix.ScaleToFit.FILL);break;}mDrawableRect.set(mBorderRect);}@Overrideprotected void onBoundsChange(@NonNull Rect bounds) {super.onBoundsChange(bounds);mBounds.set(bounds);updateShaderMatrix();}@Overridepublic void draw(@NonNull Canvas canvas) {if (mRebuildShader) {BitmapShader bitmapShader = new BitmapShader(mBitmap, mTileModeX, mTileModeY);if (mTileModeX == Shader.TileMode.CLAMP && mTileModeY == Shader.TileMode.CLAMP) {bitmapShader.setLocalMatrix(mShaderMatrix);}mBitmapPaint.setShader(bitmapShader);mRebuildShader = false;}if (mOval) {if (mBorderWidth > 0) {canvas.drawOval(mDrawableRect, mBitmapPaint);canvas.drawOval(mBorderRect, mBorderPaint);} else {canvas.drawOval(mDrawableRect, mBitmapPaint);}} else {if (any(mCornersRounded)) {float radius = mCornerRadius;if (mBorderWidth > 0) {canvas.drawRoundRect(mDrawableRect, radius, radius, mBitmapPaint);canvas.drawRoundRect(mBorderRect, radius, radius, mBorderPaint);redrawBitmapForSquareCorners(canvas);redrawBorderForSquareCorners(canvas);} else {canvas.drawRoundRect(mDrawableRect, radius, radius, mBitmapPaint);redrawBitmapForSquareCorners(canvas);}} else {canvas.drawRect(mDrawableRect, mBitmapPaint);if (mBorderWidth > 0) {canvas.drawRect(mBorderRect, mBorderPaint);}}}}private void redrawBitmapForSquareCorners(Canvas canvas) {if (all(mCornersRounded)) {// no square cornersreturn;}if (mCornerRadius == 0) {return; // no round corners}float left = mDrawableRect.left;float top = mDrawableRect.top;float right = left + mDrawableRect.width();float bottom = top + mDrawableRect.height();float radius = mCornerRadius;if (!mCornersRounded[Corner.TOP_LEFT]) {mSquareCornersRect.set(left, top, left + radius, top + radius);canvas.drawRect(mSquareCornersRect, mBitmapPaint);}if (!mCornersRounded[Corner.TOP_RIGHT]) {mSquareCornersRect.set(right - radius, top, right, radius);canvas.drawRect(mSquareCornersRect, mBitmapPaint);}if (!mCornersRounded[Corner.BOTTOM_RIGHT]) {mSquareCornersRect.set(right - radius, bottom - radius, right, bottom);canvas.drawRect(mSquareCornersRect, mBitmapPaint);}if (!mCornersRounded[Corner.BOTTOM_LEFT]) {mSquareCornersRect.set(left, bottom - radius, left + radius, bottom);canvas.drawRect(mSquareCornersRect, mBitmapPaint);}}private void redrawBorderForSquareCorners(Canvas canvas) {if (all(mCornersRounded)) {// no square cornersreturn;}if (mCornerRadius == 0) {return; // no round corners}float left = mDrawableRect.left;float top = mDrawableRect.top;float right = left + mDrawableRect.width();float bottom = top + mDrawableRect.height();float radius = mCornerRadius;float offset = mBorderWidth / 2;if (!mCornersRounded[Corner.TOP_LEFT]) {canvas.drawLine(left - offset, top, left + radius, top, mBorderPaint);canvas.drawLine(left, top - offset, left, top + radius, mBorderPaint);}if (!mCornersRounded[Corner.TOP_RIGHT]) {canvas.drawLine(right - radius - offset, top, right, top, mBorderPaint);canvas.drawLine(right, top - offset, right, top + radius, mBorderPaint);}if (!mCornersRounded[Corner.BOTTOM_RIGHT]) {canvas.drawLine(right - radius - offset, bottom, right + offset, bottom, mBorderPaint);canvas.drawLine(right, bottom - radius, right, bottom, mBorderPaint);}if (!mCornersRounded[Corner.BOTTOM_LEFT]) {canvas.drawLine(left - offset, bottom, left + radius, bottom, mBorderPaint);canvas.drawLine(left, bottom - radius, left, bottom, mBorderPaint);}}@Overridepublic int getOpacity() {return PixelFormat.TRANSLUCENT;}@Overridepublic int getAlpha() {return mBitmapPaint.getAlpha();}@Overridepublic void setAlpha(int alpha) {mBitmapPaint.setAlpha(alpha);invalidateSelf();}@Overridepublic ColorFilter getColorFilter() {return mBitmapPaint.getColorFilter();}@Overridepublic void setColorFilter(ColorFilter cf) {mBitmapPaint.setColorFilter(cf);invalidateSelf();}@Overridepublic void setDither(boolean dither) {mBitmapPaint.setDither(dither);invalidateSelf();}@Overridepublic void setFilterBitmap(boolean filter) {mBitmapPaint.setFilterBitmap(filter);invalidateSelf();}@Overridepublic int getIntrinsicWidth() {return mBitmapWidth;}@Overridepublic int getIntrinsicHeight() {return mBitmapHeight;}/*** @return the corner radius.*/public float getCornerRadius() {return mCornerRadius;}/*** @param corner the specific corner to get radius of.* @return the corner radius of the specified corner.*/public float getCornerRadius(@Corner int corner) {return mCornersRounded[corner] ? mCornerRadius : 0f;}/*** Sets all corners to the specified radius.** @param radius the radius.* @return the {@link RoundedDrawable} for chaining.*/public RoundedDrawable setCornerRadius(float radius) {setCornerRadius(radius, radius, radius, radius);return this;}/*** Sets the corner radius of one specific corner.** @param corner the corner.* @param radius the radius.* @return the {@link RoundedDrawable} for chaining.*/public RoundedDrawable setCornerRadius(@Corner int corner, float radius) {if (radius != 0 && mCornerRadius != 0 && mCornerRadius != radius) {throw new IllegalArgumentException("Multiple nonzero corner radii not yet supported.");}if (radius == 0) {if (only(corner, mCornersRounded)) {mCornerRadius = 0;}mCornersRounded[corner] = false;} else {if (mCornerRadius == 0) {mCornerRadius = radius;}mCornersRounded[corner] = true;}return this;}/*** Sets the corner radii of all the corners.** @param topLeft top left corner radius.* @param topRight top right corner radius* @param bottomRight bototm right corner radius.* @param bottomLeft bottom left corner radius.* @return the {@link RoundedDrawable} for chaining.*/public RoundedDrawable setCornerRadius(float topLeft, float topRight, float bottomRight,float bottomLeft) {Set<Float> radiusSet = new HashSet<>(4);radiusSet.add(topLeft);radiusSet.add(topRight);radiusSet.add(bottomRight);radiusSet.add(bottomLeft);radiusSet.remove(0f);if (radiusSet.size() > 1) {throw new IllegalArgumentException("Multiple nonzero corner radii not yet supported.");}if (!radiusSet.isEmpty()) {float radius = radiusSet.iterator().next();if (Float.isInfinite(radius) || Float.isNaN(radius) || radius < 0) {throw new IllegalArgumentException("Invalid radius value: " + radius);}mCornerRadius = radius;} else {mCornerRadius = 0f;}mCornersRounded[Corner.TOP_LEFT] = topLeft > 0;mCornersRounded[Corner.TOP_RIGHT] = topRight > 0;mCornersRounded[Corner.BOTTOM_RIGHT] = bottomRight > 0;mCornersRounded[Corner.BOTTOM_LEFT] = bottomLeft > 0;return this;}public float getBorderWidth() {return mBorderWidth;}public RoundedDrawable setBorderWidth(float width) {mBorderWidth = width;mBorderPaint.setStrokeWidth(mBorderWidth);return this;}public int getBorderColor() {return mBorderColor.getDefaultColor();}public RoundedDrawable setBorderColor(@ColorInt int color) {return setBorderColor(ColorStateList.valueOf(color));}public ColorStateList getBorderColors() {return mBorderColor;}public RoundedDrawable setBorderColor(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_CENTER;}if (mScaleType != scaleType) {mScaleType = scaleType;updateShaderMatrix();}return this;}public Shader.TileMode getTileModeX() {return mTileModeX;}public RoundedDrawable setTileModeX(Shader.TileMode tileModeX) {if (mTileModeX != tileModeX) {mTileModeX = tileModeX;mRebuildShader = true;invalidateSelf();}return this;}public Shader.TileMode getTileModeY() {return mTileModeY;}public RoundedDrawable setTileModeY(Shader.TileMode tileModeY) {if (mTileModeY != tileModeY) {mTileModeY = tileModeY;mRebuildShader = true;invalidateSelf();}return this;}private static boolean only(int index, boolean[] booleans) {for (int i = 0, len = booleans.length; i < len; i++) {if (booleans[i] != (i == index)) {return false;}}return true;}private static boolean any(boolean[] booleans) {for (boolean b : booleans) {if (b) { return true; }}return false;}private static boolean all(boolean[] booleans) {for (boolean b : booleans) {if (b) { return false; }}return true;}public Bitmap toBitmap() {return drawableToBitmap(this);}
}
RoundedTransformationBuilder.java

public final class RoundedTransformationBuilder {private final DisplayMetrics mDisplayMetrics;private float[] mCornerRadii = new float[] { 0, 0, 0, 0 };private boolean mOval = false;private float mBorderWidth = 0;private ColorStateList mBorderColor =ColorStateList.valueOf(RoundedDrawable.DEFAULT_BORDER_COLOR);private ImageView.ScaleType mScaleType = ImageView.ScaleType.FIT_CENTER;public RoundedTransformationBuilder() {mDisplayMetrics = Resources.getSystem().getDisplayMetrics();}public RoundedTransformationBuilder scaleType(ImageView.ScaleType scaleType) {mScaleType = scaleType;return this;}/*** Set corner radius for all corners in px.** @param radius the radius in px* @return the builder for chaining.*/public RoundedTransformationBuilder cornerRadius(float radius) {mCornerRadii[Corner.TOP_LEFT] = radius;mCornerRadii[Corner.TOP_RIGHT] = radius;mCornerRadii[Corner.BOTTOM_RIGHT] = radius;mCornerRadii[Corner.BOTTOM_LEFT] = radius;return this;}/*** Set corner radius for a specific corner in px.** @param corner the corner to set.* @param radius the radius in px.* @return the builder for chaning.*/public RoundedTransformationBuilder cornerRadius(int corner, float radius) {mCornerRadii[corner] = radius;return this;}/*** Set corner radius for all corners in density independent pixels.** @param radius the radius in density independent pixels.* @return the builder for chaining.*/public RoundedTransformationBuilder cornerRadiusDp(float radius) {return cornerRadius(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, radius, mDisplayMetrics));}/*** Set corner radius for a specific corner in density independent pixels.** @param corner the corner to set* @param radius the radius in density independent pixels.* @return the builder for chaining.*/public RoundedTransformationBuilder cornerRadiusDp(int corner, float radius) {return cornerRadius(corner,TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, radius, mDisplayMetrics));}/*** Set the border width in pixels.** @param width border width in pixels.* @return the builder for chaining.*/public RoundedTransformationBuilder borderWidth(float width) {mBorderWidth = width;return this;}/*** Set the border width in density independent pixels.** @param width border width in density independent pixels.* @return the builder for chaining.*/public RoundedTransformationBuilder borderWidthDp(float width) {mBorderWidth = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, width, mDisplayMetrics);return this;}/*** Set the border color.** @param color the color to set.* @return the builder for chaining.*/public RoundedTransformationBuilder borderColor(int color) {mBorderColor = ColorStateList.valueOf(color);return this;}/*** Set the border color as a {@link ColorStateList}.** @param colors the {@link ColorStateList} to set.* @return the builder for chaining.*/public RoundedTransformationBuilder borderColor(ColorStateList colors) {mBorderColor = colors;return this;}/*** Sets whether the image should be oval or not.** @param oval if the image should be oval.* @return the builder for chaining.*/public RoundedTransformationBuilder oval(boolean oval) {mOval = oval;return this;}/*** Creates a {@link Transformation} for use with picasso.** @return the {@link Transformation}*/public Transformation build() {return new Transformation() {@Override public Bitmap transform(Bitmap source) {Bitmap transformed = RoundedDrawable.fromBitmap(source).setScaleType(mScaleType).setCornerRadius(mCornerRadii[0], mCornerRadii[1], mCornerRadii[2], mCornerRadii[3]).setBorderWidth(mBorderWidth).setBorderColor(mBorderColor).setOval(mOval).toBitmap();if (!source.equals(transformed)) {source.recycle();}return transformed;}@Override public String key() {return "r:" + Arrays.toString(mCornerRadii)+ "b:" + mBorderWidth+ "c:" + mBorderColor+ "o:" + mOval;}};}
}

使用:

//picasso 弧度圆角头像Transformation transformation = new RoundedTransformationBuilder().borderColor(Color.TRANSPARENT).borderWidthDp(0).cornerRadiusDp(6)//圆角角度  像素.oval(false).build();
Picasso.with(this).load(avatar).transform(transformation).placeholder(R.drawable.default_avatar).into(holder.avatar);

圆角图片相关类下载:




感谢

更多推荐

学习笔记之——Android中的Picasso实现圆形头像、圆角图片工具类

本文发布于:2024-03-23 20:45:55,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1742633.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:圆形   学习笔记   头像   圆角   工具

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!