Android에서 ImageView는 기본적으로 사각형입니다. ImageView에서 둥근 사각형으로 만들려면 (비트 맵의 네 모서리를 모두 둥근 사각형으로 자르십시오)?
ShapeableImageView
원형 또는 둥근 imageView를 만들어야합니다 stackoverflow.com/a/61086632/7666442
Android에서 ImageView는 기본적으로 사각형입니다. ImageView에서 둥근 사각형으로 만들려면 (비트 맵의 네 모서리를 모두 둥근 사각형으로 자르십시오)?
ShapeableImageView
원형 또는 둥근 imageView를 만들어야합니다 stackoverflow.com/a/61086632/7666442
답변:
이것은 반응이 늦었지만 이것을 찾는 다른 사람들을 위해 다음 코드를 수행하여 이미지 모서리를 수동으로 둥글게 만들 수 있습니다.
이것은 내 코드가 아니지만 사용했으며 훌륭하게 작동합니다. 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;
}
}
이것이 누군가를 돕기를 바랍니다!
위의 답변이 작동하는 동안 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);
다른 방법에 비해이 방법의 장점은 다음과 같습니다.
이 코드를 기반 으로 RoundedImageView 를 만들었습니다. 이 로직을 ImageView로 감싸고 적절한 ScaleType
지원과 선택적인 둥근 테두리를 추가합니다 .
/ example / res / layout / rounded_item.xml
모든 소스가 하드 코딩 될 때 왜 이미지 src를 지정합니까? 좋은 데모, 너무 과잉.
또 다른 쉬운 방법은 모서리 반경과 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>
둥근 모양으로 클리핑하는 것이 View
API 21 의 클래스에 추가되었습니다 .
그냥 이렇게 :
res / drawable / round_outline.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="10dp" />
...
</shape>
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를 사용하여 이미지를 설정 해야하는 경우이 해결 방법을 사용할 수 있습니다.
android:clipToOutline
, 하나를 사용해야합니다 android:outlineProvider="background"
.
Support 라이브러리의 v21에는 이제 이에 대한 솔루션이 있습니다.이를 RoundedBitmapDrawable 이라고 합니다 .
기본적으로 일반 Drawable과 같습니다. 단지 클리핑의 모서리 반경을 지정하면 다음과 같습니다.
setCornerRadius(float cornerRadius)
따라서 Bitmap src
and로 시작하면 ImageView
다음과 같이 보일 것입니다.
RoundedBitmapDrawable dr = RoundedBitmapDrawableFactory.create(res, src);
dr.setCornerRadius(cornerRadius);
imageView.setImageDrawable(dr);
android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory
때문에 v4
또한 지원합니다.
v4
지원 라이브러리는 아니지만까지 REVISION 21
지원 라이브러리
scaleType
centerCrop
(지원 라이브러리 v25.3.1)
나는 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" />
산출:
이것이 도움이되기를 바랍니다.
Canvas.clipPath()
경우에 따라 발생할 수 있습니다 java.lang.UnsupportedOperationException
. 참조 stackoverflow.com/questions/13248904/...
android:background
하지만에는 작동 하지 않습니다 android:src
.
빠른 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>
scaleType="fitXY"
적절하게 보이지 않습니다. @ThemBones
두 가지 방법 모두 작동하는 솔루션을 만드는 데 매우 도움이된다는 것을 알았습니다. 여기 내 합성 버전은 픽셀과 독립적이며 나머지 모퉁이가 같은 사각형 모서리를 가질 수 있습니다 (일반 사용 사례). 위의 두 가지 솔루션 덕분에 :
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);
}
도움이 되었기를 바랍니다!
둥근 이미지 여기를 사용하여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);
또는 Picasso
Square에서 라이브러리 를 사용할 수 있습니다 .
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);
둥근 모서리에만 모든 대답이 너무 복잡해 보였으므로 이미지 주위에 약간의 공간이있는 경우를 대비하여 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>
버전을 시작으로 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());
둥근 모서리 위젯으로 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);
}
}
최근에는 글라이드의 생성 된 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
과 options
PARAMS에
@GlideExtension
주석 클래스를 그냥 갔다 .transform(new RoundedCorners(px))
곳에 px
동일합니다 ( int px = Math.round(cornerRadius * (context.getResources().getDisplayMetrics().xdpi / DisplayMetrics.DENSITY_DEFAULT));
).
이미지 뷰를 형성 할 수 있는 멋진 라이브러리 가 있습니다.
예를 들면 다음과 같습니다.
<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>
결과:
다음은 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로 미리보기 :
ImageView
둥근 사각형을 확장 하고 그려야합니다.
이미지 주위에 프레임을 원할 경우 레이아웃에서 이미지보기 위에 둥근 프레임을 겹쳐 놓을 수도 있습니다.
FrameLayout
예를 들어 프레임을 원본 이미지와 겹쳐 놓으십시오 . 의 첫 번째 요소는 FrameLayout
반올림하려는 이미지입니다. 그런 다음 ImageView
프레임으로 다른 것을 추가하십시오 . 두 번째 ImageView
는 원본 위에 표시 ImageView
되므로 Android는 orignal 위에 내용을 그립니다 ImageView
.
FrameLayout
넣고 둥근 프레임으로 ImageView
다른 것을 추가하십시오 ImageView
. 이렇게하면 첫 번째 ImageView
는 선택한 사진 ImageFrame
을 표시하고 두 번째 는 둥근 프레임을 표시합니다.
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);
이 순수한 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>
위의 조지 월터스 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;
}
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>
친구에게 도움이 될 수 있습니다.
클리핑하지 않는 이유는 draw()
무엇입니까?
내 해결책은 다음과 같습니다.
암호:
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;
}
}
}
다음은 둥근 사각형 레이아웃 개체를 만들어 그 안에있는 모든 자식 개체 주위에 둥근 사각형을 그립니다. 또한 레이아웃 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;
}
}
코 틀린
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
먼저 답변을 주셔서 감사합니다. 직사각형 이미지를 정사각형 이미지로 변환하고 채우기 색상이 매개 변수로 전달되도록 수정 된 버전입니다.
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;
}
글라이드 라이브러리를 사용하는 경우 도움이 될 것입니다.
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));
}
이미지가 인터넷에있는 경우 가장 좋은 방법은 글라이드를 사용하는 것입니다 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);
}
});
centerCrop
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");
ImageView
.
여기에 리디렉션 된 질문에 대한 답변 : "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;
}
글라이드 라이브러리와 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);
}
});
글라이드와 코 틀린을 사용하는 사람들에게는 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)
roundCorners
위와 같이 확장 기능을 추가 했 습니까? @ Dr.aNdRO