web-dev-qa-db-ja.com

角の丸い背景を持つImageViewをマスクする

私はCustom ListViewにはImageViewTextViewが含まれます。すべてが正常に動作しています。

私が欲しいのは、丸い角にあるリストに表示される画像です。 Webサービスから、長方形の画像を取得します。しかし、私は以下のようにラウンドコーナーImageViewに表示したいです。

enter image description here

誰でも私に丸角で画像をマスクする方法を教えてもらえますか?

私はすでに以下のようにドローアブルファイルを作成してみて、ImageViewのsrcとして適用しました。しかし、私のために働くものは何もありません。

<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>
32
GrIsHu

別の方法を使用することをお勧めします。

1つのFrameLayoutと2つのImageViewでできます。

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

画像は透明な円で見ることができます。

17
MengMeng

最良の方法は、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);
}
_

注意:

  1. OnDraw()呼び出し内にオブジェクトを作成するのは良くありません。したがって、最初はペイントとシェーダーを別の場所に置く必要があります。これはおそらく、画像ビットマップをビューに設定するときに実行できます。
  2. Canvasは、ハードウェアテクスチャに支えられていない場合、保存および復元する必要があります。ここでの一般的なアイデアはここでは言及しません。
  3. setWillNotDraw(false);をコンストラクターに追加することを忘れないでください。

追加の参照:

  1. https://sriramramani.wordpress.com/2012/12/21/shaders/ にはShadersに関する情報があります。
  2. http://mxr.mozilla.org/mozilla-central/source/mobile/Android/base/ShapedButton.Java Android版Firefoxのボタンを湾曲させるためにPathを使用します。
  3. http://sriramramani.wordpress.com/2012/08/27/constructing-squishy-buttons/ には、ICSのCanvas保存、復元、および特殊なケースに関する情報があります。
31
sriramramani

他の人が持っているように、私はピカソをお勧めします。私のActivityクラスの1つに対するこのコードは、私にとってはうまくいきました。それは、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

20
David Geller

RoundedBitmapDrawablev4サポートライブラリ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);
14
Godfrey Duke

シンプルなソリューションと黒の背景なし

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);
    }
}
5
0x131313

次のコードを参照してください。これは、必要なことを正確に行います。

https://github.com/vinc3m1/RoundedImageView

あなたがカスタムビューを望んでいないならあなたが言ったように、次のアイデアを試してください

角が丸く、背景が透明な9パッチ.png画像(フォトフレームなど)を作成します。

次に、次のように2つの画像ビューで相対レイアウト/ FrameLayoutを作成します

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

画像ソース以外の同じ属性を持つ画像ビューと、myRoundCornerFrameとしてソースを持つ画像ビューが別の画像ビューの上にあることを確認してください。

3
Jayabal

Android-shape-imageview を試してください-それはあなたを助けるはずです。

2
jimpanzer

既にGlideを使用している場合、 RequestOptions で効果を達成できます:

RequestOptions requestOptions = new RequestOptions();
requestOptions = requestOptions.transforms(new CenterCrop(), new RoundedCorners(radiusInPixels));
Glide.with(context)
    .load(imageUrl)
    .apply(requestOptions)
    .into(imageView);
1
rednuht

drawable hdpiフォルダーにroundimage.xmlという名前のxmlファイルを作成し、次のコードを試してください。

<?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);
}
0
Abb

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

1つのこと-この行を削除した場合:

setWillNotDraw(false);

すべてがまだ機能します。必要かどうかわかりませんか?

0
mmd1080

ここで私がやったこと..しかし、私の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);
        }
0
Prachi