Как преобразовать изображение в другую форму?

На самом деле я хочу преобразовать изображение в указанную форму на картинке. Я пробовал много подобных вопросов в SO, но ни один из них не помог. Вы можете посоветовать использовать drawable на переднем плане imageView, но я должен программно установить передний план, который действителен только api> 23. Может ли кто-нибудь помочь мне решить эту проблему?

Вы можете видеть на изображении, что есть фон изображения. Я хочу программно преобразовать изображение в эту форму.

Даже я пытался использовать Gradient Drawable, но безуспешно

Код:

GradientDrawable gradientDrawable= new GradientDrawable();
        float[] radii = new float[8];
        radii[0] = 15; // Goes clockwise, so this is the top left corner start position.
        radii[1] = 15; // top left end position.
        radii[2] = 15;
        radii[3] = 15;
        radii[4]=0;
        radii[5]=0;
        radii[6] = 15;
        radii[7] = 15;
        gradientDrawable.setCornerRadii(radii);
        holder.img.setBackgroundDrawable(gradientDrawable);

Как преобразовать изображение в другую форму?

setBackgroundDrawable устарел. Вместо этого используйте setBackground.
Kunu 01.05.2018 16:31
1
1
80
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Вы можете изменить метод onDraw вашего класса imageView, применив clipPath:

@Override
protected void onDraw(Canvas canvas) {
    float[] radii = new float[8];
    radii[0] = radius; // Goes clockwise, so this is the top left corner start position.
    radii[1] = radius; // top left end position.
    radii[2] = radius;
    radii[3] = radius;
    // Skipping 4 and 5 because thats the bottom right corner.
    radii[6] = radius;
    radii[7] = radius;
    Path clipPath = new Path();
    clipPath.addRoundRect(new RectF(0, 0, this.getWidth(), this.getHeight()), radii, Path.Direction.CW);
    canvas.clipPath(clipPath);
    super.onDraw(canvas);
}

ссылки:

Сэр, большое спасибо за ваш ответ, но он показывает, что конструктор не может разрешить для этой строки clipPath.addRoundRect (новый RectF (0, 0, this.getWidth (), this.getHeight (), радиусы, Path.Direction.CW);

anonymous 01.05.2018 15:47

@ user8027365 Я забыл скобу для закрытия RectF, исправил в примере.

wolfenrain 01.05.2018 15:50

Хм, а вы добавили его в свой расширенный класс ImageView? Или вы создаете свой ImageView по-другому?

wolfenrain 01.05.2018 16:08

это ничего не меняет

anonymous 01.05.2018 16:11

Если вы хотите создать изображение, которое можно рисовать, вы можете установить другой радиус для другого угла, например

<corners
    android:topRightRadius = "15dp"
    android:topLeftRadius = "15dp"
    android:bottomLeftRadius = "15dp"/>

Кроме того, вы можете использовать Градиент для создания фонового изображения и использования setCornerRadii для переменного радиуса угла.

Пример для GradientDrawable

GradientDrawable gradientDrawable= new GradientDrawable();
gradientDrawable.setCornerRadii(15,15,15,15,15,15,0,0);

void setCornerRadii (float[] radii)

Specifies radii for each of the 4 corners. For each corner, the array contains 2 values, [X_radius, Y_radius]. The corners are ordered top-left, top-right, bottom-right, bottom-left. This property is honored only when the shape is of type RECTANGLE.

для установки цвета используйте метод gradientDrawable.setColor(YOUR_COLOR), и вы можете использовать несколько цветов для градиентного вида.

Здесь (15,15,15,15,15,15,0,0) предложите радиус X и радиус Y для всех 4 углов, начиная с верхнего левого угла.

не могли бы вы рассказать, как использовать Градиент Рисуем в моем случае @Kunu

anonymous 01.05.2018 15:49

я должен установить этот градиент в качестве фона? @Kunu

anonymous 01.05.2018 16:15

Если вы используете один цвет, он будет таким же, как обычный фон.

Kunu 01.05.2018 16:16

Это ничего не меняет сэр

anonymous 01.05.2018 16:21

Можете ли вы обновить свой вопрос с помощью обновленного кода?

Kunu 01.05.2018 16:22
setBackgroundDrawable устарел. Вместо этого используйте setBackground.
Kunu 01.05.2018 16:27

Наконец, я решил свою проблему, взяв ссылку из из этого и это

Наконец, класс ImageView выглядит так:

public class RoundedImageView extends ImageView {

private Path mMaskPath;
private Paint mMaskPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private int mCornerRadius = 10;

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

    init();
}

public RoundedImageView(Context context, AttributeSet attributeSet) {
    super(context, attributeSet);

    init();
}

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

    init();
}

private void init() {
    ViewCompat.setLayerType(this, ViewCompat.LAYER_TYPE_SOFTWARE, null);
    mMaskPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
}


public void setCornerRadius(int cornerRadius) {
    mCornerRadius = cornerRadius;
    generateMaskPath(getWidth(), getHeight());
    invalidate();
}

@Override
protected void onSizeChanged(int w, int h, int oldW, int oldH) {
    super.onSizeChanged(w, h, oldW, oldH);

    if (w != oldW || h != oldH) {
        generateMaskPath(w, h);
    }
}

private void generateMaskPath(int w, int h) {
    mMaskPath = new Path();
    float[] radii = new float[8];
    radii[0] = 20; // Goes clockwise, so this is the top left corner start position.
    radii[1] = 20; // top left end position.
    radii[2] = 20;
    radii[3] = 20;
    // Skipping 4 and 5 because thats the bottom right corner.
    radii[6] = 20;
    radii[7] = 20;
    mMaskPath.addRoundRect(new RectF(0,0,w,h), radii, Path.Direction.CW);
    mMaskPath.setFillType(Path.FillType.INVERSE_WINDING);
}

@SuppressLint("WrongConstant")
@Override
protected void onDraw(Canvas canvas) {
    if (canvas.isOpaque()) { // If canvas is opaque, make it transparent
        canvas.saveLayerAlpha(0, 0, canvas.getWidth(), canvas.getHeight(), 255, Canvas.HAS_ALPHA_LAYER_SAVE_FLAG);
    }

    super.onDraw(canvas);

    if (mMaskPath != null) {
        canvas.drawPath(mMaskPath, mMaskPaint);
    }
}
 }

Другие вопросы по теме