如何在Circle中显示图像视图?

时间:2014-07-25 11:54:19

标签: android image shapes

我继续使用图片视图来自图库或从相机拍摄照片我们默认情况下在广场上查看图片后,我们可以使用Android中的SDK将视图更改为圆形。 / p>

是否有可能只使用SDK裁剪图像。

如果有人对此有所了解,请帮助我们。

3 个答案:

答案 0 :(得分:4)

这个主题有很多图书馆和帖子。以下是一些:

  1. CircularImageView
  2. CircleImageView
  3. Stackoverflow post 1
  4. Stackoverflow post 2
  5. Stackoverflow post 3
  6. Stackoverflow post 4 //这是使用xml

答案 1 :(得分:1)

使用此:

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

}

现在在xml中声明ImageView:

 <yourpackage.RoundedImageView
                    android:id="@+id/iv"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:src="@drawable/bg" />

答案 2 :(得分:0)

尝试以下代码:

只需将以下代码粘贴为类:

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

另外,将stylable放在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>