모서리가 둥근 ImageView를 만드는 방법은 무엇입니까?


573

Android에서 ImageView는 기본적으로 사각형입니다. ImageView에서 둥근 사각형으로 만들려면 (비트 맵의 ​​네 모서리를 모두 둥근 사각형으로 자르십시오)?


도움이 될 수 있습니다 stackoverflow.com/questions/26850780/…
— Mangesh

이전의 더 복잡한 답변 아래에 숨겨져있는 더 복잡한 답변은 제가 지금 받아 드린 답변이어야한다고 생각합니다 : RoundedBitmapDrawable , v4 지원 라이브러리 개정판 21에 추가됨
— Jonik

내부에 ImageView가있는 CardView를 사용하는 것이 가장 쉬운 방법입니다. 여기 예제를보십시오. stackoverflow.com/a/41479670/4516797
— Taras Vovkovych

이 라이브러리는 매우 유용합니다.
— grrigore

이것을 확인하십시오 우리는 ShapeableImageView원형 또는 둥근 imageView를 만들어야합니다 stackoverflow.com/a/61086632/7666442
— Nilesh Rathod

답변:


544

이것은 반응이 늦었지만 이것을 찾는 다른 사람들을 위해 다음 코드를 수행하여 이미지 모서리를 수동으로 둥글게 만들 수 있습니다.

http://www.ruibm.com/?p=184

이것은 내 코드가 아니지만 사용했으며 훌륭하게 작동합니다. ImageHelper 클래스 내에서 도우미로 사용하고 주어진 이미지에 필요한 페더 양을 전달하기 위해 조금 확장했습니다.

최종 코드는 다음과 같습니다.

package com.company.app.utils;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Bitmap.Config;
import android.graphics.PorterDuff.Mode;

public class ImageHelper {
    public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, int pixels) {
        Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap
                .getHeight(), Config.ARGB_8888);
        Canvas canvas = new Canvas(output);

        final int color = 0xff424242;
        final Paint paint = new Paint();
        final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
        final RectF rectF = new RectF(rect);
        final float roundPx = pixels;

        paint.setAntiAlias(true);
        canvas.drawARGB(0, 0, 0, 0);
        paint.setColor(color);
        canvas.drawRoundRect(rectF, roundPx, roundPx, paint);

        paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
        canvas.drawBitmap(bitmap, rect, rect, paint);

        return output;
    }
}

이것이 누군가를 돕기를 바랍니다!


4
모든 장치에서 작동하지는 않습니다. 어디에서나 변경해야합니까?
— Spring Breaker

7
200 * 200 사진을 만드는 데 거의 0.03 초가 걸리므로 이것이 최선의 해결책이라고 생각하지 않습니다.
— Jacky

2
왼쪽 상단과 오른쪽 상단 만 둥글게됩니다. 왜 ?
— Prateek

1
@ vinc3m1 솔루션 여기 github.com/makeramen/RoundedImageView 는 정말 잘 작동합니다! 또한 그의 답변을 참조하십시오 ( stackoverflow.com/a/15032283/2048266 )
— nommer

16
imageview의 스케일 유형을 설정하려고 할 때 제대로 작동하지 않고 fitXY 만 작동하고 centerCrop과 다른 사람들이 예측할 수없는 결과를 보이고 있습니다.
— Shivansh

211

위의 답변이 작동하는 동안 Romain Guy (핵심 안드로이드 개발자)는 비트 맵 복사본을 만들지 않는 셰이더를 사용하여 메모리를 덜 사용하는 블로그에서 더 나은 방법 을 보여줍니다 . 기능의 일반적인 요지는 다음과 같습니다.

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

다른 방법에 비해이 방법의 장점은 다음과 같습니다.

  • 큰 이미지를 가진 많은 메모리를 사용 하는 별도의 비트 맵 복사본을 만들지 않습니다. [대부분의 다른 답변은 여기에서]
  • 앤티 앨리어싱 지원 [vs clipPath 방법]
  • 알파 지원 [vs xfermode + porterduff 방법]
  • 하드웨어 가속 지원 [vs clipPath 방법]
  • 단지 캔버스에 한 번 그립니다 [xfermode 및 clippath 방법 대]

이 코드를 기반 으로 RoundedImageView 를 만들었습니다. 이 로직을 ImageView로 감싸고 적절한 ScaleType지원과 선택적인 둥근 테두리를 추가합니다 .


당신의 / example / res / layout / rounded_item.xml 모든 소스가 하드 코딩 될 때 왜 이미지 src를 지정합니까? 좋은 데모, 너무 과잉.
— 누군가 어딘가에

Romain Guy의 원본 샘플과 마찬가지로 샘플에 메모리 부족 문제가 있습니다. 나는 아직도 그 원인을 알지 못하지만 그의 코드와 마찬가지로 이것은 찾기가 매우 어렵습니다. OOM으로 인해 앱에서 충돌이 발생하지 않으면 앱, 앱이 발생할 때까지 여러 번 회전 할 수 있습니다 (장치, ROM 등에 따라 다름). 과거에 여기에 대해보고했습니다 : stackoverflow.com/questions/14109187/…
— Android 개발자

1
다른 사람은 메모리 부족 문제를보고하지 않으므로 코드 외부에서 잘못된 일을해야합니다. 이 예제 는보기를 그릴 때마다 다시 작성 하지 않고 어댑터에 제한된 비트 맵 세트를 올바르게 보유합니다 . 여기에 표시된 예제는 Drawable에있는 draw () 메서드의 스 니펫으로, 원본 비트 맵에 대한 참조를 사용하고 올바르게 작동합니다. 되어 있지 원래 비트 맵을 변경할 수 있지만 둥근 모서리로 렌더링하기위한 것. 가운데 자르기도 예제에서도 잘 작동합니다.
— vinc3m1

1
작동하지 않는 스크린 샷이나 장치를 제공하거나 수정 및 풀 요청을 제공하는 한 가장 생산적입니다. 장치에서 회전을 여러 번 테스트 한 결과 메모리는 동일하게 유지됩니다.
— vinc3m1

11
이미지 크기가 2048 픽셀보다 크면 작동하지 않습니다. 셰이더는 그보다 큰 텍스처를 지원하지 않습니다.
— Gábor

209

또 다른 쉬운 방법은 모서리 반경과 ImageView가있는 CardView를 사용하는 것입니다.

  <android.support.v7.widget.CardView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:cardCornerRadius="8dp"
            android:layout_margin="5dp"
            android:elevation="10dp">

            <ImageView
                android:id="@+id/roundedImageView"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:src="@drawable/image"
                android:background="@color/white"
                android:scaleType="centerCrop"
                />
        </android.support.v7.widget.CardView>

여기에 이미지 설명을 입력하십시오


5
좋은 해결 방법 인 것 같습니다. 그러나 롤리팝 이전의 이미지는 자르지 않습니다.
— Nikolai

1
만약 우리가 모든 코너가 아니라 왼쪽 상단과 오른쪽 상단에만 반경을 원한다면?
— Pratik Singhal

3
모든 뷰에서 곡선 경계를 적용하는 매우 간단하고 현명한 방법입니다.
— AMI CHARADAVA

1
좋은 해결책이지만 고도는 API 레벨 21 이상에서만 지원됩니다
— Saad Bilal

1
카드 높이를 비활성화하려면 app : cardElevation = "0dp"(Android : elevation 아님)를 사용하십시오.
— Johnny Five

148

둥근 모양으로 클리핑하는 것이 ViewAPI 21 의 클래스에 추가되었습니다 .

그냥 이렇게 :

  • 다음과 같이 둥근 모양의 드로어 블을 만듭니다.

res / drawable / round_outline.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <corners android:radius="10dp" />
    ...
</shape>
  • 드로어 블을 ImageView의 배경으로 설정하십시오. android:background="@drawable/round_outline"
  • 이 문서 에 따르면 , 당신이해야 할 모든 추가android:clipToOutline="true"

불행히도 버그가 있으며 XML 속성이 인식되지 않습니다. 운 좋게도 여전히 Java에서 클리핑을 설정할 수 있습니다.

  • 활동 또는 단편에서 : ImageView.setClipToOutline(true)

그 모습은 다음과 같습니다.

여기에 이미지 설명을 입력하십시오

노트 :

이 방법은 둥근 모양이 아닌 모든 드로어 블 모양에 적용됩니다. Drawable xml에 정의한 모양 외곽선에 ImageView를 클리핑합니다.

ImageView에 대한 특별 참고 사항

setClipToOutline()뷰의 배경이 도형 드로어 블로 설정된 경우에만 작동합니다. 이 배경 모양이 있으면 View는 모양의 윤곽선을 클리핑 및 그림자 목적으로 테두리로 취급합니다.

즉, setClipToOutline()ImageView에서 모서리를 둥글게하는 데 사용 하려면 배경을 둥근 모양으로 설정해야하므로 android:src대신 이미지를 설정 android:background해야합니다. src 대신 background를 사용하여 이미지를 설정 해야하는 경우이 해결 방법을 사용할 수 있습니다.

  • 레이아웃을 만들고 배경을 모양 드로어 블로 설정
  • 패딩없이 ImageView 주위에 레이아웃을 감싸십시오.
  • 이제 레이아웃에 다른 것을 포함하여 ImageView가 둥근 레이아웃 모양으로 표시됩니다.

10
오류 : (x) 'android'패키지의 'clipToOutline'속성에 대한 리소스 식별자를 찾을 수 없음
— Anu Martin

7
대신 android:clipToOutline, 하나를 사용해야합니다 android:outlineProvider="background".
— WindRider

2
내가 구글을 너무 좋아하는 또 다른 이유는이 버그가 거의 내 나이이고 여전히 작은 세상에 있기 때문입니다. 구글은 그것에 대해 아무런 cr * ap도주지 않는 것 같다))
— Farid

1
배경 모양의 topleft 및 topRight 모서리 만 둥글게 설정하면이 방법으로 성공하지 못하는 것 같습니다.
— Peterdk

-이 알려진 문제입니다 @AnuMartin issuetracker.google.com/issues/37036728
— 바딤 Kotov

132

Support 라이브러리의 v21에는 이제 이에 대한 솔루션이 있습니다.이를 RoundedBitmapDrawable 이라고 합니다 .

기본적으로 일반 Drawable과 같습니다. 단지 클리핑의 모서리 반경을 지정하면 다음과 같습니다.

setCornerRadius(float cornerRadius)

따라서 Bitmap srcand로 시작하면 ImageView다음과 같이 보일 것입니다.

RoundedBitmapDrawable dr = RoundedBitmapDrawableFactory.create(res, src);
dr.setCornerRadius(cornerRadius);
imageView.setImageDrawable(dr);


실제로이 android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory때문에 v4또한 지원합니다.
— deadfish

2
@deadfish 예 자사에서의 v4지원 라이브러리는 아니지만까지 REVISION 21지원 라이브러리
— tyczj

3
이 솔루션은 간단하고 최신입니다. 최소한의 코드가 필요하며 확장 성이 뛰어납니다. 로컬 파일의 이미지, 캐시 된 드로어 블 또는 Volley의 NetworkImageView를 사용하여 작업 할 수 있습니다. @Jonik이 지적한 것처럼 이것이 오늘날 받아 들여질만한 답변이라는 데 동의합니다.
— katie

2
안타깝게도 작동하지 않습니다 scaleType centerCrop(지원 라이브러리 v25.3.1)
— rocknow

67

나는 Custom ImageView에 의해 수행되었습니다.

public class RoundRectCornerImageView extends ImageView {

    private float radius = 18.0f;
    private Path path;
    private RectF rect;

    public RoundRectCornerImageView(Context context) {
        super(context);
        init();
    }

    public RoundRectCornerImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public RoundRectCornerImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    private void init() {
        path = new Path();

    }

    @Override
    protected void onDraw(Canvas canvas) {
        rect = new RectF(0, 0, this.getWidth(), this.getHeight());
        path.addRoundRect(rect, radius, radius, Path.Direction.CW);
        canvas.clipPath(path);
        super.onDraw(canvas);
    }
}

사용하는 방법:

<com.mypackage.RoundRectCornerImageView
     android:id="@+id/imageView"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:background="@drawable/image"
     android:scaleType="fitXY" />

산출:

여기에 이미지 설명을 입력하십시오

이것이 도움이되기를 바랍니다.


이것은 이미지 블러를 만듭니다
— Amit Hooda

2
android : scaleType = "centerCrop"에서도 작동하며 간단하지만 새로운 비트 맵을 만들지 않습니다. 감사!
— ernazm

1
@Hiren이 솔루션은 배경 이미지가있는 ImageView에 적합합니다. 그러나 배경색 만 있고 이미지가없는 ImageViews에서는 작동하지 않습니다. 왜 이런 일이 발생하는지 말씀해 주시겠습니까?
— user2991413

Canvas.clipPath()경우에 따라 발생할 수 있습니다 java.lang.UnsupportedOperationException. 참조 stackoverflow.com/questions/13248904/...
— 툠

1
이 솔루션은로 설정된 이미지에만 작동 android:background하지만에는 작동 하지 않습니다 android:src.
— CoolMind

64

빠른 XML 솔루션-

<android.support.v7.widget.CardView
            android:layout_width="40dp"
            android:layout_height="40dp"
            app:cardElevation="0dp"
            app:cardCornerRadius="4dp">

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/rounded_user_image"
        android:scaleType="fitXY"/>

</android.support.v7.widget.CardView>

CardView에서 원하는 너비, 높이 및 반경을 설정하고 ImageView에서 scaleType을 설정할 수 있습니다.

AndroidX에서는 <androidx.cardview.widget.CardView>


4
이 접근법은 androidx.cardview.widget.CardView와 함께 내 경우에 효과적이었습니다.
— Ivan

7
왜 이것이 더 많은 투표를하지 않는지 잘 모르십니까? 제 생각에는 라이브러리와 수많은 코드가없는 최고의 솔루션입니다 (필자의 경우 centerCrop 스케일링을 사용했지만).
— ThemBones 2016 년

1
새로운 답변이므로 아직 많은지지를받지 못했습니다. 하지만 곧 +1을 올려 놓았습니다. 감사!
— Micer

그러나 그것은 작동하지만 여기에서 이미지가 늘어나고 scaleType="fitXY"적절하게 보이지 않습니다. @ThemBones
— WIZARD

@WIZARD 이것이 ImageView에서 원하는 scaleType을 설정할 수 있다고 언급 한 이유입니다.
— Chirag Mittal

57

두 가지 방법 모두 작동하는 솔루션을 만드는 데 매우 도움이된다는 것을 알았습니다. 여기 내 합성 버전은 픽셀과 독립적이며 나머지 모퉁이가 같은 사각형 모서리를 가질 수 있습니다 (일반 사용 사례). 위의 두 가지 솔루션 덕분에 :

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, h/2, w/2, h, paint);
    }
    if (squareTR ){
        canvas.drawRect(w/2, h/2, w, h, paint);
    }
    if (squareBL ){
        canvas.drawRect(0, 0, w/2, h/2, paint);
    }
    if (squareBR ){
        canvas.drawRect(w/2, 0, w, h/2, paint);
    }


    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
    canvas.drawBitmap(input, 0,0, paint);

    return output;
}

또한 ImageView를 덮어 써서 XML로 정의 할 수 있도록했습니다. 슈퍼 콜이 여기에서 만드는 논리를 추가하고 싶을 수도 있지만 제 경우에는 도움이되지 않기 때문에 주석을 달았습니다.

    @Override
protected void onDraw(Canvas canvas) {
    //super.onDraw(canvas);
        Drawable drawable = getDrawable();

        Bitmap b =  ((BitmapDrawable)drawable).getBitmap() ;
        Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true);

        int w = getWidth(), h = getHeight();


        Bitmap roundBitmap =  CropImageView.getRoundedCornerBitmap( getContext(), bitmap,10 , w, h , true, false,true, false);
        canvas.drawBitmap(roundBitmap, 0,0 , null);
}

도움이 되었기를 바랍니다!


4
특히 굉장한, 특히 ImageView 확장
— 누군가 어딘가에

2
ImageView # onDraw ()의 논리를 유지하는 간단한 방법은 둥근 모서리 비트 맵을 ImageView의 드로어 블로 설정하고 super.onDraw ()를 남겨 비트 맵을 그리는 것입니다. RoundedCornerImageView 클래스를 만들었으며 사용법 예제는 여기에 있습니다 . 내가 사용한 getRoundedCornerBitmap ()은 픽셀에 독립적이지 않습니다.
— umbalaconmeogia

RoundedCornerImageView에 감사드립니다. 나는 그것을 사용했지만 픽셀 밀도 독립적으로 수정했습니다.
— PacificSky

umba 's RoundedCornerImageView의 소스 코드는 다음과 같습니다. code.google.com/p/android-batsg/source/browse/trunk/…
— 누군가 어딘가에

@ Caspar Harmer는 1 번의 편집 만 잘 수행합니다 ... 4 가지 조건이 있습니다. 참, 참, 거짓, 거짓으로 설정하면 상단 모서리 대신 하단 모서리를 설정하는 것처럼 변경하십시오. 그렇지 않으면 코드가 정상적으로 작동합니다. 및 squareTR은 각각 squareBL 및 squareBR에 대한 조건이다.
— TheFlash

48

둥근 이미지 여기를 사용하여ImageLoader

작성 DisplayImageOptions:

DisplayImageOptions options = new DisplayImageOptions.Builder()
    // this will make circle, pass the width of image 
    .displayer(new RoundedBitmapDisplayer(getResources().getDimensionPixelSize(R.dimen.image_dimen_menu))) 
    .cacheOnDisc(true)
    .build();

imageLoader.displayImage(url_for_image,ImageView,options);

또는 PicassoSquare에서 라이브러리 를 사용할 수 있습니다 .

Picasso.with(mContext)
    .load(com.app.utility.Constants.BASE_URL+b.image)
    .placeholder(R.drawable.profile)
    .error(R.drawable.profile)
    .transform(new RoundedTransformation(50, 4))
    .resizeDimen(R.dimen.list_detail_image_size, R.dimen.list_detail_image_size)
    .centerCrop()
    .into(v.im_user);

여기 에서 RoundedTransformation 파일을 다운로드 할 수 있습니다


1
이미지를 표시하지 않음
— Thaper Amit

3
피카소 라이브러리 하나는 훌륭하고 구현하기가 매우 쉽습니다. +1
— Hitesh

3
Picasso 라이브러리는 "자리 표시 자"및 "오류"이미지를 변환하지 않는 것 같습니다. 따라서 이미지가로드되지 않거나 (오류) 시간이 오래 걸리거나 (자리 표시 자) 이미지가 둥근 이미지로 표시되지 않습니다. github.com/square/picasso/issues/337
— Pelpotronic

RoundedCornersTransformation : github.com/wasabeef/picasso-transformations
— Massimo

Univ에서 이미지 자르기와는 작동하지 않습니다. 이미지 로더.
— Yar

26

둥근 모서리에만 모든 대답이 너무 복잡해 보였으므로 이미지 주위에 약간의 공간이있는 경우를 대비하여 XML과 공유 할 가치가있는 다른 솔루션을 찾았습니다.

다음과 같이 투명한 내용으로 경계 모양을 만듭니다.

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <corners 
        android:radius="30dp" />
    <stroke 
        android:color="#ffffffff"
        android:width="10dp" />
</shape> 

그런 다음 RelativeLayout에서 먼저 이미지를 배치 한 다음 다른 ImageView를 사용하여 셰이프 위의 동일한 위치에 배치 할 수 있습니다. 커버 모양은 테두리 너비만큼 크기가 커야합니다. 외부 반경이 정의되어 있지만 내부 반경이 이미지를 덮고 있으므로 코너 반경을 더 크게 취하십시오.

누군가에게 도움이되기를 바랍니다.

CQM 요청에 따라 상대 레이아웃 예를 편집하십시오 .

<?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" >

    <ImageView
        android:id="@+id/imageToShow"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/imgCorners"
        android:layout_alignLeft="@+id/imgCorners"
        android:layout_alignRight="@+id/imgCorners"
        android:layout_alignTop="@+id/imgCorners"
        android:background="#ffffff"
        android:contentDescription="@string/desc"
        android:padding="5dp"
        android:scaleType="centerCrop" />

    <ImageView
        android:id="@+id/imgCorners"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true"
        android:contentDescription="@string/desc"
        android:src="@drawable/corners_white" />

</RelativeLayout>

더 많은 코드, 특히 두 번째 이미지보기로 수행되는 작업과 "순서 모양"xml이 적용되는 위치 (src 또는 배경으로)에 대해 더 많은 코드로 더 자세히 설명 할 수 있습니까? 이 솔루션을 사용하면 네 모서리를 모두 독립적으로 제어 할 수 있기 때문에이 솔루션을 좋아합니다.
— CQM

1
간단한 대답 인 것처럼 보이지만 불행히도 "마스크 된"이미지보기 주위에 여백을 추가하여 바람직하지 않은 부작용이 있습니다.
— Abdalrahman Shatou

예, 모서리가 둥글고 투명한 배경이있는 PNG 그리기 가능 또는 정의되지 않은 측면이있는 경우 9 개 그리기 가능을 기반으로하는 ImageView에서도 동일하게 작동합니다.
— Christian

나는 같은 방식으로 일하고 있습니다. 방향과 다른 전화 크기에 문제가 발생하지 않는지 알고 싶습니까?
— 개장 및 무료

치수를 서로에 대해 상대적으로 유지하면 문제가 발생하지 않습니다.
— Christian

22

버전을 시작으로 1.2.0-alpha03하여의 재료 구성 요소 라이브러리 새로운있다ShapeableImageView .

다음과 같은 것을 사용할 수 있습니다.

  <com.google.android.material.imageview.ShapeableImageView
      ...
      app:shapeAppearanceOverlay="@style/roundedImageView"
      app:srcCompat="@drawable/ic_image" />

와:

  <style name="roundedImageView" parent="">
    <item name="cornerFamily">rounded</item>
    <item name="cornerSize">8dp</item>
  </style>

또는 프로그래밍 방식으로 :

float radius = getResources().getDimension(R.dimen.default_corner_radius);
imageView.setShapeAppearanceModel(imageView.getShapeAppearanceModel()
    .toBuilder()
    .setAllCorners(CornerFamily.ROUNDED,radius)
    .build());

여기에 이미지 설명을 입력하십시오


이미지에 배경색이있는 경우 현재 둥근 모서리 아래에 배경색이 나타납니다. 이미지의 scaleType 속성도 무시합니다.
— inokey

14

둥근 모서리 위젯으로 ImageView를 구현하면 이미지의 크기가 필요한 크기로 조정됩니다. 코드 형식 CaspNZ를 사용합니다.

public class ImageViewRounded extends ImageView {

    public ImageViewRounded(Context context) {
        super(context);
    }

    public ImageViewRounded(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public ImageViewRounded(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        BitmapDrawable drawable = (BitmapDrawable) getDrawable();

        if (drawable == null) {
            return;
        }

        if (getWidth() == 0 || getHeight() == 0) {
            return; 
        }

        Bitmap fullSizeBitmap = drawable.getBitmap();

        int scaledWidth = getMeasuredWidth();
        int scaledHeight = getMeasuredHeight();

        Bitmap mScaledBitmap;
        if (scaledWidth == fullSizeBitmap.getWidth() && scaledHeight == fullSizeBitmap.getHeight()) {
            mScaledBitmap = fullSizeBitmap;
        } else {
            mScaledBitmap = Bitmap.createScaledBitmap(fullSizeBitmap, scaledWidth, scaledHeight, true /* filter */);
        }

        Bitmap roundBitmap = ImageUtilities.getRoundedCornerBitmap(getContext(), mScaledBitmap, 5, scaledWidth, scaledHeight,
                false, false, false, false);
        canvas.drawBitmap(roundBitmap, 0, 0, null);

    }

}

12
ImageUtilities는 어디에서 왔습니까?
— JasonWyatt

1
@JasonWyatt 아래 sorrodos 게시물보기
— Damjan

12

최근에는 글라이드의 생성 된 API를 사용하는 또 다른 방법이 있습니다. 초기 작업이 필요하지만 실제 코드를 작성하기 때문에 Glide의 모든 기능을 유연하게 사용할 수 있으므로 장기적으로는 좋은 솔루션이라고 생각합니다. 또한 사용법은 매우 간단하고 깔끔합니다.

먼저 Glide 버전 4 이상을 설정하십시오 .

implementation 'com.github.bumptech.glide:glide:4.6.1'
annotationProcessor 'com.github.bumptech.glide:compiler:4.6.1'

그런 다음 Glid의 앱 모듈 클래스를 만들어 주석 처리를 시작하십시오.

@GlideModule
public final class MyAppGlideModule extends AppGlideModule {}

그런 다음 실제로 작업을 수행하는 Glide 확장을 만듭니다. 원하는대로 할 수 있도록 사용자 정의 할 수 있습니다.

@GlideExtension
public class MyGlideExtension {

    private MyGlideExtension() {}

    @NonNull
    @GlideOption
    public static RequestOptions roundedCorners(RequestOptions options, @NonNull Context context, int cornerRadius) {
        int px = Math.round(cornerRadius * (context.getResources().getDisplayMetrics().xdpi / DisplayMetrics.DENSITY_DEFAULT));
        return options.transforms(new RoundedCorners(px));
    }
}

이러한 파일을 추가 한 후 프로젝트를 빌드하십시오.

그런 다음 코드에서 다음과 같이 사용하십시오.

GlideApp.with(this)
        .load(imageUrl)
        .roundedCorners(getApplicationContext(), 5)
        .into(imageView);

사이에 공백을 추가하는 것을 잊지 마세요 RequestOptions과 optionsPARAMS에
— StevenTB에게

끝난. 입력 해 주셔서 감사합니다.
— Sir Codesalot

.roundedCorners가 오지 않으면 다른 것을 설정해야합니까? 프로젝트를 재건 한 후에도
— Dr. aNdRO

이것은 나를 위해 일했습니다. 감사합니다. 내가 사용하지 않는 것이 간단 발견 @GlideExtension주석 클래스를 그냥 갔다 .transform(new RoundedCorners(px))곳에 px동일합니다 ( int px = Math.round(cornerRadius * (context.getResources().getDisplayMetrics().xdpi / DisplayMetrics.DENSITY_DEFAULT));).
— Michael Osofsky

10

이미지 뷰를 형성 할 수 있는 멋진 라이브러리 가 있습니다.

예를 들면 다음과 같습니다.

<com.github.siyamed.shapeimageview.mask.PorterShapeImageView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:siShape="@drawable/shape_rounded_rectangle"
    android:src="@drawable/neo"
    app:siSquare="true"/>

모양 정의 :

<shape android:shape="rectangle" xmlns:android="http://schemas.android.com/apk/res/android">
    <corners
        android:topLeftRadius="18dp"
        android:topRightRadius="18dp"
        android:bottomLeftRadius="18dp"
        android:bottomRightRadius="18dp" />
    <solid android:color="@color/black" />
</shape>

결과:

결과


1
이것은 국경을 추가하고 어떤 모양이든 사용할 수있는 것처럼 훌륭하고 훨씬 더 많은 일을합니다
— Adam Kis

8

다음은 imageView를 재정의하는 간단한 예제입니다. 그런 다음 레이아웃 디자이너에서 이미지를 사용하여 미리 볼 수도 있습니다.

public class RoundedImageView extends ImageView {

    public RoundedImageView(Context context) {
        super(context);
    }

    public RoundedImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public RoundedImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public RoundedImageView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    public void setImageDrawable(Drawable drawable) {
        float radius = 0.1f;
        Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
        RoundedBitmapDrawable rid = RoundedBitmapDrawableFactory.create(getResources(), bitmap);
        rid.setCornerRadius(bitmap.getWidth() * radius);
        super.setImageDrawable(rid);
    }
}

빠른 솔루션입니다. 반지름은 모든 모서리에 사용되며 비트 맵 너비의 백분율을 기반으로합니다.

방금 setImageDrawable둥근 비트 맵 드로어 블에 대한 지원 v4 메서드를 재정의 하고 사용했습니다.

용법:

<com.example.widgets.RoundedImageView
        android:layout_width="39dp"
        android:layout_height="39dp"
        android:src="@drawable/your_drawable" />

imageView 및 사용자 정의 imageView로 미리보기 :

여기에 이미지 설명을 입력하십시오


이것은 모든 상황에서 작동합니다. 감사합니다. 당신은 내 하루를 구했습니다.
— Mehul Solanki

7

ImageView둥근 사각형을 확장 하고 그려야합니다.

이미지 주위에 프레임을 원할 경우 레이아웃에서 이미지보기 위에 둥근 프레임을 겹쳐 놓을 수도 있습니다.

FrameLayout예를 들어 프레임을 원본 이미지와 겹쳐 놓으십시오 . 의 첫 번째 요소는 FrameLayout반올림하려는 이미지입니다. 그런 다음 ImageView프레임으로 다른 것을 추가하십시오 . 두 번째 ImageView는 원본 위에 표시 ImageView되므로 Android는 orignal 위에 내용을 그립니다 ImageView.


감사합니다. 그러나 ImageView에는 setDrawable 메소드 만 있습니다 .ImageView의 DrawDraw를 내 이미지의 내용으로 설정 한 다음 ImageView 위에 둥근 프레임을 겹쳐 놓을 수 있습니까?
— 마이클

죄송합니다. 불분명했습니다. 나는 레이아웃에 중첩을 의미했다. 따라서 (즉) 그것을 FrameLayout넣고 둥근 프레임으로 ImageView다른 것을 추가하십시오 ImageView. 이렇게하면 첫 번째 ImageView는 선택한 사진 ImageFrame을 표시하고 두 번째 는 둥근 프레임을 표시합니다.
— MrSnowflake

올바른-FrameLayout을 사용하면 한 이미지 / 뷰를 다른 이미지 / 뷰와 오버레이 할 수 있습니다. FrameLayout의 android : foreground 태그를 사용할 수도 있습니다.
— Richard Le Mesurier

7

Romain Guy가있는 곳입니다.

다음과 같이 축소 된 버전입니다.

Bitmap bitmap = ((BitmapDrawable) getResources().getDrawable(R.drawable.image)).getBitmap();

Bitmap bitmapRounded = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), bitmap.getConfig());
Canvas canvas = new Canvas(bitmapRounded);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setShader(new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
canvas.drawRoundRect((new RectF(0.0f, 0.0f, bitmap.getWidth(), bitmap.getHeight())), 10, 10, paint);

imageView.setImageBitmap(bitmapRounded);

슬프게도 작동하지만 여기의 나머지 솔루션과 마찬가지로 현재 비트 맵을 사용하는 대신 새 비트 맵을 만듭니다.
— Android 개발자

실제로는 아닙니다. bitmapRounded가 반복해서 사용됩니다. 드로어 블 캔버스에 액세스 할 수있는 경우 새 비트 맵을 생성하는 대신 직접 드로우 방법을 사용할 수 있습니다.
— Alex

어떻게합니까? 특별한 드로어 블을 사용하지 않고 단일 비트 맵 만 처리하고 프로세스 끝에 setImageBitmap을 사용한다고 가정하십시오. 어떻게 그런 일을 할 수 있습니까?
— 안드로이드 개발자


둘 다 비트 맵을 변경하지 않지만 사용자 정의 드로어 블 및 사용자 정의 이미지 뷰를 사용하여 래핑합니다. 이것은 내가 요구 한 것이 아닙니다. 비트 맵 자체를 어떻게 변경합니까?
— 안드로이드 개발자

7

이 순수한 XML 솔루션은 제 경우에는 충분했습니다. http://www.techrepublic.com/article/pro-tip-round-corners-on-an-android-imageview-with-this-hack/

편집하다

간단히 말해서 대답은 다음과 같습니다.

/ res / drawable 폴더에서 frame.xml 파일을 작성하십시오. 여기에서 모서리가 둥글고 투명한 중심이 있는 간단한 사각형을 정의합니다 .

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
     <solid android:color="#00ffffff" />
     <padding android:left="6dp"
        android:top="6dp"
        android:right="6dp"
        android:bottom="6dp" />
     <corners android:radius="12dp" />
     <stroke android:width="6dp" android:color="#ffffffff" />
</shape>

레이아웃 파일에서 표준 ImageView와 중첩 된 FrameLayout을 포함하는 LinearLayout을 추가합니다. FrameLayout은 패딩과 사용자 정의 드로어 블을 사용하여 둥근 모서리의 환상을 제공합니다.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:layout_gravity="center"
    android:gravity="center" 
    android:background="#ffffffff">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="6dp"
        android:src="@drawable/tr"/>

    <FrameLayout 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

        <ImageView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:padding="6dp"
            android:src="@drawable/tr"/>

        <ImageView 
             android:src="@drawable/frame"
             android:layout_width="match_parent"
             android:layout_height="match_parent" />

    </FrameLayout>

</LinearLayout>

좋은 생각, 나는 그것을 사용하지 않은 ImageView 코너를 보여주기 위해 사용
— Gal Rom

6

위의 조지 월터스 II (George Walters II)에 대한 소품은 방금 그의 대답을 취하여 개별 모서리를 다르게 반올림하도록 지원하기 위해 조금 확장했습니다. 이것은 조금 더 최적화 될 수 있지만 (일부 목표 rect가 겹치게 됨) 전체가 아닙니다.

이 스레드는 약간 오래되었지만 Android에서 ImageView의 모서리를 둥글게하는 방법에 대한 Google 쿼리의 최고 결과 중 하나입니다.

/**
 * Use this method to scale a bitmap and give it specific rounded corners.
 * @param context Context object used to ascertain display density.
 * @param bitmap The original bitmap that will be scaled and have rounded corners applied to it.
 * @param upperLeft Corner radius for upper left.
 * @param upperRight Corner radius for upper right.
 * @param lowerRight Corner radius for lower right.
 * @param lowerLeft Corner radius for lower left.
 * @param endWidth Width to which to scale original bitmap.
 * @param endHeight Height to which to scale original bitmap.
 * @return Scaled bitmap with rounded corners.
 */
public static Bitmap getRoundedCornerBitmap(Context context, Bitmap bitmap, float upperLeft,
        float upperRight, float lowerRight, float lowerLeft, int endWidth,
        int endHeight) {
    float densityMultiplier = context.getResources().getDisplayMetrics().density;

    // scale incoming bitmap to appropriate px size given arguments and display dpi
    bitmap = Bitmap.createScaledBitmap(bitmap, 
            Math.round(endWidth * densityMultiplier),
            Math.round(endHeight * densityMultiplier), true);

    // create empty bitmap for drawing
    Bitmap output = Bitmap.createBitmap(
            Math.round(endWidth * densityMultiplier),
            Math.round(endHeight * densityMultiplier), Config.ARGB_8888);

    // get canvas for empty bitmap
    Canvas canvas = new Canvas(output);
    int width = canvas.getWidth();
    int height = canvas.getHeight();

    // scale the rounded corners appropriately given dpi
    upperLeft *= densityMultiplier;
    upperRight *= densityMultiplier;
    lowerRight *= densityMultiplier;
    lowerLeft *= densityMultiplier;

    Paint paint = new Paint();
    paint.setAntiAlias(true);
    paint.setColor(Color.WHITE);

    // fill the canvas with transparency
    canvas.drawARGB(0, 0, 0, 0);

    // draw the rounded corners around the image rect. clockwise, starting in upper left.
    canvas.drawCircle(upperLeft, upperLeft, upperLeft, paint);
    canvas.drawCircle(width - upperRight, upperRight, upperRight, paint);
    canvas.drawCircle(width - lowerRight, height - lowerRight, lowerRight, paint);
    canvas.drawCircle(lowerLeft, height - lowerLeft, lowerLeft, paint);

    // fill in all the gaps between circles. clockwise, starting at top.
    RectF rectT = new RectF(upperLeft, 0, width - upperRight, height / 2);
    RectF rectR = new RectF(width / 2, upperRight, width, height - lowerRight);
    RectF rectB = new RectF(lowerLeft, height / 2, width - lowerRight, height);
    RectF rectL = new RectF(0, upperLeft, width / 2, height - lowerLeft);

    canvas.drawRect(rectT, paint);
    canvas.drawRect(rectR, paint);
    canvas.drawRect(rectB, paint);
    canvas.drawRect(rectL, paint);

    // set up the rect for the image
    Rect imageRect = new Rect(0, 0, width, height);

    // set up paint object such that it only paints on Color.WHITE
    paint.setXfermode(new AvoidXfermode(Color.WHITE, 255, AvoidXfermode.Mode.TARGET));

    // draw resized bitmap onto imageRect in canvas, using paint as configured above
    canvas.drawBitmap(bitmap, imageRect, imageRect, paint);

    return output;
}

밀도 승수를 추가하고 개별적으로 둥근 모서리를 지원하기 위해 +1. 솔루션이 제대로 작동하지 않아 실제로 솔루션을 맨 위에 사용했지만 매우 도움이되었습니다! 아래의 복합 솔루션을 참조하십시오.
— Caspar Harmer

6

imageView아래와 같이 모양을 적용하십시오 .

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >
    <solid android:color="#faf5e6" />
    <stroke
        android:width="1dp"
        android:color="#808080" />
    <corners android:radius="15dp" />
    <padding
        android:bottom="5dp"
        android:left="5dp"
        android:right="5dp"
        android:top="5dp" />
</shape>

친구에게 도움이 될 수 있습니다.


6

클리핑하지 않는 이유는 draw()무엇입니까?

내 해결책은 다음과 같습니다.

  • 클리핑으로 RelativeLayout 확장
  • ImageView (또는 다른보기)를 레이아웃에 넣습니다.

암호:

public class RoundRelativeLayout extends RelativeLayout {

    private final float radius;

    public RoundRelativeLayout(Context context, AttributeSet attrs) {
        super(context, attrs);

        TypedArray attrArray = context.obtainStyledAttributes(attrs,
                R.styleable.RoundRelativeLayout);
        radius = attrArray.getDimension(
                R.styleable.RoundRelativeLayout_radius, 0);
    }

    private boolean isPathValid;
    private final Path path = new Path();

    private Path getRoundRectPath() {
        if (isPathValid) {
            return path;
        }

        path.reset();

        int width = getWidth();
        int height = getHeight();
        RectF bounds = new RectF(0, 0, width, height);

        path.addRoundRect(bounds, radius, radius, Direction.CCW);
        isPathValid = true;
        return path;
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        canvas.clipPath(getRoundRectPath());
        super.dispatchDraw(canvas);
    }

    @Override
    public void draw(Canvas canvas) {
        canvas.clipPath(getRoundRectPath());
        super.draw(canvas);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        int oldWidth = getMeasuredWidth();
        int oldHeight = getMeasuredHeight();
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        int newWidth = getMeasuredWidth();
        int newHeight = getMeasuredHeight();
        if (newWidth != oldWidth || newHeight != oldHeight) {
            isPathValid = false;
        }
    }

}

1
나는이 접근법을 좋아한다. 내 RoundImageView를 만드는 데 사용했습니다. 고마워
— 파스칼

하드웨어 가속을 설정 한 경우 작동하지 않습니다. 맞습니까? 쉬운 해결 방법을 보지 못했습니다 ...
— secureboot

결과를 드로어 블로하여 콘텐츠 주위에 윤곽선 (AKA 획)을 추가하고 모서리의 일부만 둥글게 만들 수있는 방법을 보여줄 수 있습니까?
— 안드로이드 개발자

5

다음은 둥근 사각형 레이아웃 개체를 만들어 그 안에있는 모든 자식 개체 주위에 둥근 사각형을 그립니다. 또한 레이아웃 xml 파일을 사용하지 않고 프로그래밍 방식으로보기 및 레이아웃을 만드는 방법을 보여줍니다.

package android.example;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.ViewGroup.LayoutParams;
import android.widget.LinearLayout;
import android.widget.TextView;

public class MessageScreen extends Activity {
 /** Called when the activity is first created. */
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  int mainBackgroundColor = Color.parseColor("#2E8B57");
  int labelTextColor = Color.parseColor("#FF4500");
  int messageBackgroundColor = Color.parseColor("#3300FF");
  int messageTextColor = Color.parseColor("#FFFF00");

  DisplayMetrics metrics = new DisplayMetrics();
  getWindowManager().getDefaultDisplay().getMetrics(metrics);
  float density = metrics.density;
  int minMarginSize = Math.round(density * 8);
  int paddingSize = minMarginSize * 2;
  int maxMarginSize = minMarginSize * 4;

  TextView label = new TextView(this);
  /*
   * The LayoutParams are instructions to the Layout that will contain the
   * View for laying out the View, so you need to use the LayoutParams of
   * the Layout that will contain the View.
   */
  LinearLayout.LayoutParams labelLayoutParams = new LinearLayout.LayoutParams(
    LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
  label.setLayoutParams(labelLayoutParams);
  label.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);
  label.setPadding(paddingSize, paddingSize, paddingSize, paddingSize);
  label.setText(R.string.title);
  label.setTextColor(labelTextColor);

  TextView message = new TextView(this);
  RoundedRectangle.LayoutParams messageLayoutParams = new RoundedRectangle.LayoutParams(
 LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
  /*
   * This is one of the calls must made to force a ViewGroup to call its
   * draw method instead of just calling the draw method of its children.
   * This tells the RoundedRectangle to put some extra space around the
   * View.
   */
  messageLayoutParams.setMargins(minMarginSize, paddingSize,
    minMarginSize, maxMarginSize);
  message.setLayoutParams(messageLayoutParams);
  message.setTextSize(TypedValue.COMPLEX_UNIT_SP, paddingSize);
  message.setText(R.string.message);
  message.setTextColor(messageTextColor);
  message.setBackgroundColor(messageBackgroundColor);

  RoundedRectangle messageContainer = new RoundedRectangle(this);
  LinearLayout.LayoutParams messageContainerLayoutParams = new LinearLayout.LayoutParams(
    LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
  messageContainerLayoutParams.setMargins(paddingSize, 0, paddingSize, 0);
  messageContainer.setLayoutParams(messageContainerLayoutParams);
  messageContainer.setOrientation(LinearLayout.VERTICAL);
  /*
   * This is one of the calls must made to force a ViewGroup to call its
   * draw method instead of just calling the draw method of its children.
   * This tells the RoundedRectangle to color the the exta space that was
   * put around the View as well as the View. This is exterior color of
   * the RoundedRectangle.
   */
  messageContainer.setBackgroundColor(mainBackgroundColor);
  /*
   * This is one of the calls must made to force a ViewGroup to call its
   * draw method instead of just calling the draw method of its children.
   * This is the interior color of the RoundedRectangle. It must be
   * different than the exterior color of the RoundedRectangle or the
   * RoundedRectangle will not call its draw method.
   */
  messageContainer.setInteriorColor(messageBackgroundColor);
  // Add the message to the RoundedRectangle.
  messageContainer.addView(message);

  //
  LinearLayout main = new LinearLayout(this);
  LinearLayout.LayoutParams mainLayoutParams = new LinearLayout.LayoutParams(
    LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
  main.setLayoutParams(mainLayoutParams);
  main.setOrientation(LinearLayout.VERTICAL);
  main.setBackgroundColor(mainBackgroundColor);
  main.addView(label);
  main.addView(messageContainer);

  setContentView(main);
 }
}

RoundedRectangle 레이아웃 객체의 클래스는 다음과 같이 정의됩니다.

/**
 *  A LinearLayout that draws a rounded rectangle around the child View that was added to it.
 */
package android.example;

import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.widget.LinearLayout;

/**
 * A LinearLayout that has rounded corners instead of square corners.
 * 
 * @author Danny Remington
 * 
 * @see LinearLayout
 * 
 */
public class RoundedRectangle extends LinearLayout {
 private int mInteriorColor;

 public RoundedRectangle(Context p_context) {
  super(p_context);
 }

 public RoundedRectangle(Context p_context, AttributeSet attributeSet) {
  super(p_context, attributeSet);
 }

 // Listener for the onDraw event that occurs when the Layout is drawn.
 protected void onDraw(Canvas canvas) {
  Rect rect = new Rect(0, 0, getWidth(), getHeight());
  RectF rectF = new RectF(rect);
  DisplayMetrics metrics = new DisplayMetrics();
  Activity activity = (Activity) getContext();
  activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
  float density = metrics.density;
  int arcSize = Math.round(density * 10);

  Paint paint = new Paint();
  paint.setColor(mInteriorColor);

  canvas.drawRoundRect(rectF, arcSize, arcSize, paint);
 }

 /**
  * Set the background color to use inside the RoundedRectangle.
  * 
  * @param Primitive int - The color inside the rounded rectangle.
  */
 public void setInteriorColor(int interiorColor) {
  mInteriorColor = interiorColor;
 }

 /**
  * Get the background color used inside the RoundedRectangle.
  * 
  * @return Primitive int - The color inside the rounded rectangle.
  */
 public int getInteriorColor() {
  return mInteriorColor;
 }

}

5

코 틀린

import android.graphics.BitmapFactory
import android.os.Bundle
import android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory
import kotlinx.android.synthetic.main.activity_main.*

val bitmap = BitmapFactory.decodeResource(resources, R.drawable.myImage)
val rounded = RoundedBitmapDrawableFactory.create(resources, bitmap)
rounded.cornerRadius = 20f
profileImageView.setImageDrawable(rounded)

ImageView원형 을 만들기 위해 다음 cornerRadius과 같이 변경할 수 있습니다 .

rounded.isCircular = true

4

먼저 답변을 주셔서 감사합니다. 직사각형 이미지를 정사각형 이미지로 변환하고 채우기 색상이 매개 변수로 전달되도록 수정 된 버전입니다.

public static Bitmap getRoundedBitmap(Bitmap bitmap, int pixels, int color) {

    Bitmap inpBitmap = bitmap;
    int width = 0;
    int height = 0;
    width = inpBitmap.getWidth();
    height = inpBitmap.getHeight();

    if (width <= height) {
        height = width;
    } else {
        width = height;
    }

    Bitmap output = Bitmap.createBitmap(width, height, Config.ARGB_8888);
    Canvas canvas = new Canvas(output);

    final Paint paint = new Paint();
    final Rect rect = new Rect(0, 0, width, height);
    final RectF rectF = new RectF(rect);
    final float roundPx = pixels;

    paint.setAntiAlias(true);
    canvas.drawARGB(0, 0, 0, 0);
    paint.setColor(color);
    canvas.drawRoundRect(rectF, roundPx, roundPx, paint);

    paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
    canvas.drawBitmap(inpBitmap, rect, rect, paint);

    return output;
}

4

글라이드 라이브러리를 사용하는 경우 도움이 될 것입니다.

Glide.with(getApplicationContext())
     .load(image_url)
     .asBitmap()
     .centerCrop()
     .into(new BitmapImageViewTarget(imageView) {
        @Override
        protected void setResource(Bitmap resource) {
          RoundedBitmapDrawable circularBitmapDrawable =
                       RoundedBitmapDrawableFactory.create(getApplicationContext().getResources(), resource);
          circularBitmapDrawable.setCornerRadius(dpToPx(10));
          circularBitmapDrawable.setAntiAlias(true);
          imageView.setImageDrawable(circularBitmapDrawable);
        }
     });


public int dpToPx(int dp) {
  DisplayMetrics displayMetrics = getApplicationContext().getResources().getDisplayMetrics();
  return Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
}

글라이드 버전 4 이상을 사용하는 경우 --- RequestOptions requestOptions = new RequestOptions (); requestOptions = requestOptions.transforms (new CenterCrop (), 새로운 RoundCorners (16)); Glide.with (itemView.getContext ()) .load (item.getImage ()) .apply (requestOptions) .into (mProgramThumbnail);
— B.shruti

3

이미지가 인터넷에있는 경우 가장 좋은 방법은 글라이드를 사용하는 것입니다 RoundedBitmapDrawableFactory(API 21에서-지원 라이브러리에서 사용 가능).

 Glide.with(ctx).load(url).asBitmap().centerCrop().into(new BitmapImageViewTarget(imageView) {
    @Override
    protected void setResource(Bitmap res) {
        RoundedBitmapDrawable bitmapDrawable =
             RoundedBitmapDrawableFactory.create(ctx.getResources(), res);
        bitmapDrawable.setCircular(true);//comment this line and uncomment the next line if you dont want it fully cricular
        //circularBitmapDrawable.setCornerRadius(cornerRadius);
        imageView.setImageDrawable(bitmapDrawable);
    }
});

그러나 이것은 우아한 API이지만 .centerInside가 누락 된 것 같습니다. 따라서 xml을 사용하여 이러한 매개 변수를 정의하는 것이 좋습니다.
— carl

이미지가 리소스에 있고 사용할 필요가있을 때도 유용합니다.centerCrop
— Artyom

3

ImageView레이아웃 에서만 사용할 수 있고를 glide사용하면이 방법을 사용하여 둥근 모서리를 적용 할 수 있습니다.

먼저 gradle write에서

compile 'com.github.bumptech.glide:glide:3.7.0'

모서리가 둥근 이미지의 경우

public void loadImageWithCorners(String url, ImageView view) {
    Glide.with(context)
            .load(url)
            .asBitmap()
            .centerCrop()
            .placeholder(R.color.gray)
            .error(R.color.gray)
            .diskCacheStrategy(DiskCacheStrategy.SOURCE)
            .into(new BitmapImageViewTarget(view) {
                @Override
                protected void setResource(Bitmap resource) {
                    RoundedBitmapDrawable circularBitmapDrawable =
                            RoundedBitmapDrawableFactory.create(context.getResources(), resource);
                    circularBitmapDrawable.setCornerRadius(32.0f); // radius for corners
                    view.setImageDrawable(circularBitmapDrawable);
                }
            });
}

전화 방법 :

loadImageWithCorners("your url","your imageview");

이것은 HTTP 요청을 통해 이미지를로드하는 라이브러리를 추가하며 질문과 관련이 없습니다.
— creativecreatoror

어떤 라이브러리가로드됩니까? 이미지 로딩의 경우 글라이드와 스 니펫을 사용하여 글라이드 자체의 방법과 클래스를 기반으로합니다. 다른 도서관은 추가 할 필요가 없습니다
— Deep Patel

글라이드는 주로 HTTP를 통해 이미지를로드하기위한 라이브러리이지만 OP는의 모서리를 둥글게하는 방법을 알고 싶어했습니다 ImageView.
— creativecreatoror

2

여기에 리디렉션 된 질문에 대한 답변 : "Android에서 원형 ImageView를 만드는 방법?"

public static Bitmap getRoundBitmap(Bitmap bitmap) {

    int min = Math.min(bitmap.getWidth(), bitmap.getHeight());

    Bitmap bitmapRounded = Bitmap.createBitmap(min, min, bitmap.getConfig());

    Canvas canvas = new Canvas(bitmapRounded);
    Paint paint = new Paint();
    paint.setAntiAlias(true);
    paint.setShader(new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
    canvas.drawRoundRect((new RectF(0.0f, 0.0f, min, min)), min/2, min/2, paint);

    return bitmapRounded;
}

2

글라이드 라이브러리와 RoundedBitmapDrawableFactory 클래스 의 도움으로 쉽게 달성 할 수 있습니다. 원형 자리 표시 자 이미지를 만들어야 할 수도 있습니다.

    Glide.with(context)
        .load(imgUrl)
        .asBitmap()
        .placeholder(R.drawable.placeholder)
        .error(R.drawable.placeholder)
        .into(new BitmapImageViewTarget(imgProfilePicture) {
            @Override
            protected void setResource(Bitmap resource) {
                RoundedBitmapDrawable drawable = RoundedBitmapDrawableFactory.create(context.getResources(),
                        Bitmap.createScaledBitmap(resource, 50, 50, false));
                drawable.setCornerRadius(10); //drawable.setCircular(true);
                imgProfilePicture.setImageDrawable(drawable);
            }
        });

2

글라이드와 코 틀린을 사용하는 사람들에게는 RequestBuilder

fun <T> GlideRequest<T>.roundCorners(cornerRadius: Int) =
    apply(RequestOptions().transform(RoundedCorners(cornerRadius)))

로 사용;

 GlideApp.with(context)
            .load(url)
            .roundCorners(context.resources.getDimension(R.dimen.radius_in_dp).toInt())
            .into(imgView)

.roundedCorners가 오지 않으면 다른 것을 설정해야합니까?
— Dr. aNdRO

roundCorners위와 같이 확장 기능을 추가 했 습니까? @ Dr.aNdRO
— dgngulcan

적절한 예를 제시하십시오! 이 답변은 혼란 스러워요!
— Junia Montana
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.