Подтвердить что ты не робот

Маска ImageView с круглым фоном угла

У меня есть Custom Listview, который содержит ImageView, TextView Все работает нормально.

Я хочу, чтобы изображение отображалось в списке в круглом углу. Из Webservice я получаю изображения в форме прямоугольника. Но я хочу отобразить его в Round Round ImageView, как показано ниже.

enter image description here

Может ли кто-нибудь показать мне, как я могу замаскировать изображение в круглом углу?

Я уже пробовал, создав файл, как показано ниже, и применил его как src в imageview. Но ничего не работает для меня.

<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
   <item>
      <shape android:shape="oval" >
         <solid android:color="#FFFFFF" />
         <padding
            android:bottom="10dp"
            android:left="10dp"
            android:right="10dp"
            android:top="10dp" />
         <corners android:radius="5dp" />
      </shape>
   </item>
   <item>
      <shape android:shape="oval" >
         <padding
            android:bottom="5dp"
            android:left="5dp"
            android:right="5dp"
            android:top="5dp" />
         <solid android:color="#FFFFFF" />
      </shape>
   </item>
</layer-list>

Редакция:

enter image description here Пожалуйста, помогите мне.

Любая помощь будет оценена.

Спасибо

Я применил ниже решение:

 <FrameLayout
        android:id="@+id/imagemaskframe"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="10dp" >

        <ImageView
            android:id="@+id/op_ivpic"
            android:layout_width="80dp"
            android:layout_height="80dp"
            android:layout_gravity="center"
            android:scaleType="fitXY" />

        <ImageView
            android:id="@+id/iv_mask_op"
            android:layout_width="80dp"
            android:layout_height="80dp"
            android:layout_gravity="center"
            android:adjustViewBounds="true"
            android:scaleType="fitXY"
            android:src="@drawable/imgmask" />
    </FrameLayout>
4b9b3361

Ответ 1

Я предлагаю вам использовать другой метод:

Один FrameLayout и два ImageView могут это сделать.

<FrameLayout>
    <ImageView />  your image 
    <ImageView />  put a image which has a transparent circle in it
</FrameLayout>

тогда ваше изображение можно увидеть через прозрачный круг.

Ответ 2

Лучший способ - сделать это в Canvas с помощью операций PorterDuff и/или Shaders. Скажем, ваш Bitmap доступен и сохраняется в mBitmap.

Вариант 1: Использование шейдеров.

@Override
public void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    // Load the bitmap as a shader to the paint.
    final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    final Shader shader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
    paint.setShader(shader);

    // Draw a circle with the required radius.
    final float halfWidth = canvas.getWidth()/2;
    final float halfHeight = canvas.getHeight()/2;
    final float radius = Math.max(halfWidth, halfHeight);
    canvas.drawCircle(halfWidth, halfHeight, radius, paint);
}

Вариант 2: использование режима PorterDuff.

@Override
public void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    // Create a circular path.
    final float halfWidth = canvas.getWidth()/2;
    final float halfHeight = canvas.getHeight()/2;
    final float radius = Math.max(halfWidth, halfHeight);
    final Path path = new Path();
    path.addCircle(halfWidth, halfHeight, radius, Path.Direction.CCW);

    final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
    canvas.drawPath(path, paint);
}

Примечание:

  • Нехорошо создавать объекты внутри вызовов onDraw(). Следовательно, вы должны сначала иметь свою краску и шейдер в другом месте. Это можно сделать, если вы установите растровое изображение изображения в представление.
  • Canvas может потребоваться сохранить и восстановить, если он не подкреплен текстурой оборудования. Общие идеи вокруг него здесь не упоминаются.
  • Не забудьте добавить конструктор setWillNotDraw(false);.

Дополнительные ссылки:

Ответ 3

Я бы определенно рекомендовал Пикассо, как и другие. Этот бит кода для одного из моих классов активности сделал для меня трюк. Он использовал цвет, который я определил в color.xml, и простой макет (показано ниже).

       ImageView profile_image = (ImageView) findViewById(R.id.profile_image);
       mContext = profile_image.getContext();

        // ----------------------------------------------------------------
        // apply rounding to image
        // see: https://github.com/vinc3m1/RoundedImageView
        // ----------------------------------------------------------------
        Transformation transformation = new RoundedTransformationBuilder()
                .borderColor(getResources().getColor(R.color.my_special_orange))
                .borderWidthDp(5)
                .cornerRadiusDp(50)
                .oval(false)
                .build();

        Picasso.with(mContext)
                .load("http://{some_url}.jpg")
                .fit()
                .transform(transformation)
                .into(profile_image);

И соответствующий файл макета:   

    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="fill_parent"
        android:layout_height="120dp"
        android:layout_alignParentTop="true"
        android:layout_alignParentStart="true"
        android:padding="12dp">


        <ImageView
            android:id="@+id/profile_image"
            android:layout_width="80dp"
            android:layout_height="80dp"
            android:layout_gravity="center"/>

        <LinearLayout
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="80dp"
            android:layout_gravity="center"
            android:padding="12dp">


            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textAppearance="?android:attr/textAppearanceLarge"
                android:text="First-Name"
                android:id="@+id/profile_first_name"
                />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textAppearance="?android:attr/textAppearanceSmall"
                android:text="Lastname"
                android:id="@+id/profile_last_name" />
        </LinearLayout>



        </LinearLayout>
</RelativeLayout>

Здесь результат:

image

Ответ 4

A RoundedBitmapDrawable из v4 Support Library может применяться к ImageView для достижения желаемого эффекта:

ImageView imageView = (ImageView)findViewById(R.id.imageView);
Bitmap avatar = BitmapFactory.decodeResource(getResources(), R.drawable.avatar);
RoundedBitmapDrawable roundDrawable = RoundedBitmapDrawableFactory.create(getResources(), avatar);
roundDrawable.setCircular(true);
imageView.setImageDrawable(roundDrawable);

Ответ 5

Простое решение и без черного фона!

public class CircleImageView extends ImageView
{
    public CircleImageView(Context context)
    {
        super(context);
    }

    @Override
    protected void onDraw(Canvas canvas)
    {
        // Create a circular path.
        final float halfWidth = canvas.getWidth()/2;
        final float halfHeight = canvas.getHeight()/2;
        final float radius = Math.max(halfWidth, halfHeight);
        final Path path = new Path();
        path.addCircle(halfWidth, halfHeight, radius, Path.Direction.CCW);

        canvas.clipPath(path);

        super.onDraw(canvas);
    }
}

Ответ 6

Обратитесь к следующему коду, который точно выполняет то, что вам нужно.

https://github.com/vinc3m1/RoundedImageView

Как вы сказали, если вам не нужен пользовательский вид, попробуйте следующую идею

создать 9 патч .png изображение (например, фоторамку) с закругленным углом и прозрачным фоном

затем создайте Относительный макет /FrameLayout с двумя представлениями изображения, как показано ниже.

<RelativeLayout ....>
   <ImageView android:id="@+id/myImage" ..>
   <ImageView android:id="@+id/myRoundCorner" android:src="@drawable/myRoundCornerdFrame">
</RelativeLayout>

убедитесь, что оба изображения имеют одни и те же атрибуты, кроме источника изображения, а также убедитесь, что изображение, у которого есть источник как myRoundCornerFrame, должно быть больше (сверху) другого изображения.

Ответ 8

создайте файл xml с именем roundimage.xml в папке hdpi и попробуйте следующий код.

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" 
android:shape="rectangle">
        <solid android:color="@android:color/darker_gray" />
       <corners android:bottomRightRadius="50dip"
        android:bottomLeftRadius="50dip"  
        android:topRightRadius="50dip"
        android:topLeftRadius="50dip"/>
   </shape>

затем включите файл в фоновое изображение в качестве

android:background="@drawable/roundimage"

Я прошу вас изменить размеры и цвета в соответствии с вашими требованиями.

используйте этот код

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

используйте это, поскольку это работает.

если вы хотите квадратный угол, используйте этот

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

Ответ 9

вот что я сделал.. но мой bg img был прямоугольником.

        ImageView ivLogo;
        ivLogo=(ImageView)fragment.mRoot.findViewById(R.id.iv_offer_logo);

то при настройке изображения

      if(response.result.Partner.logo_url != null &&                 !response.result.Partner.logo_url.equals("")){
                 ivLogo.setPadding(3,3,3,3);
               DisplayImageOptions options =
                 WWFunctions.getDisplayImage(0);
            ImageLoader imageLoader = ImageLoader.getInstance();
                    imageLoader.init(ImageLoaderConfiguration.createDefault(mOfferDetailsFragment.getActivity() ));
          imageLoader.displayImage(response.result.Partner.logo_url, ivLogo, options);
        }

Ответ 10

Развернувшись на ответ sriramramani (включая исправление для черного фона), вот мой простой ImageView в целом:

public class ExampleImageView extends ImageView {
  public ExampleImageView(Context context) {
    super(context);

    init();
  }

  public ExampleImageView(Context context, @Nullable AttributeSet attrs) {
    super(context, attrs);

    init();
  }

  public ExampleImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);

    init();
  }

  void init() {
    setWillNotDraw(false);
  }

  @Override
  protected void onDraw(Canvas canvas) {

    int count = canvas.saveLayer(0, 0, getWidth(), getHeight(), null,
            Canvas.MATRIX_SAVE_FLAG |
                    Canvas.CLIP_SAVE_FLAG |
                    Canvas.HAS_ALPHA_LAYER_SAVE_FLAG |
                    Canvas.FULL_COLOR_LAYER_SAVE_FLAG |
                    Canvas.CLIP_TO_LAYER_SAVE_FLAG);

    super.onDraw(canvas);

    // Create a circular path.
    final float halfWidth = canvas.getWidth()/2;
    final float halfHeight = canvas.getHeight()/2;
    final float radius = Math.max(halfWidth, halfHeight);
    final Path path = new Path();
    path.addCircle(halfWidth, halfHeight, radius, Path.Direction.CCW);

    final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
    canvas.drawPath(path, paint);

    canvas.restoreToCount(count);
  }
}

Одна вещь - если я удалю эту строку:

setWillNotDraw(false);

Все по-прежнему работает. Не уверен, что это необходимо?