Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 要使用曲线做图像边圆角,要删除图像中出现的线吗_Android_Android Layout_Canvas_Paint - Fatal编程技术网

Android 要使用曲线做图像边圆角,要删除图像中出现的线吗

Android 要使用曲线做图像边圆角,要删除图像中出现的线吗,android,android-layout,canvas,paint,Android,Android Layout,Canvas,Paint,我用曲线裁剪图像边的圆角,希望删除图像中出现的线条,正如你在文章中提到的输出屏幕中看到的那样 我使用quadTo裁剪圆弧形状,然后应用arcTo完成参考图像中提到的圆角(平滑) 参考图像 ArcLayout.java import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Outline;

我用曲线裁剪图像边的圆角,希望删除图像中出现的线条,正如你在文章中提到的输出屏幕中看到的那样

我使用quadTo裁剪圆弧形状,然后应用arcTo完成参考图像中提到的圆角(平滑)

参考图像

ArcLayout.java

 import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Outline;
    import android.graphics.Paint;
    import android.graphics.Path;
    import android.graphics.PorterDuff;
    import android.graphics.PorterDuffXfermode;
    import android.graphics.RectF;
    import android.os.Build;
    import android.support.annotation.RequiresApi;
    import android.support.v4.view.ViewCompat;
    import android.util.AttributeSet;
    import android.view.View;
    import android.view.ViewOutlineProvider;
    import android.widget.FrameLayout;

    public class ArcLayout extends FrameLayout {

        private ArcLayoutSettings settings;

        private int height = 0;

        private int width = 0;

        private Path clipPathOne;

        private Path clipPathOneCurv;

        private Path clipPathTwoCurv;

        private float radius = 0, margin = 0;

        private final RectF cornerRect = new RectF();


        public ArcLayout(Context context) {
            super(context);
            init(context, null);
        }

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

        public void init(Context context, AttributeSet attrs) {
            settings = new ArcLayoutSettings(context, attrs);
            settings.setElevation(ViewCompat.getElevation(this));
            radius = settings.getRadius();
            margin = settings.getMargin();

            /**
             * If hardware acceleration is on (default from API 14), clipPathOne worked correctly
             * from API 18.
             *
             * So we will disable hardware Acceleration if API < 18
             *
             * https://developer.android.com/guide/topics/graphics/hardware-accel.html#unsupported
             * Section #Unsupported Drawing Operations
             */
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {
                setLayerType(View.LAYER_TYPE_SOFTWARE, null);
            }
        }

        private Path createClipPath(int position) {
            final Path path = new Path();

            float arcHeight = settings.getArcHeight();

            switch (position) {
                case ArcLayoutSettings.POSITION_BOTTOM_CURVE:
                    if (settings.isCropInside()) {
                        path.moveTo(0, 0);
                        path.lineTo(0, height);
                        path.quadTo(width / 2, height - 2 * arcHeight, width, height);
                        path.lineTo(width, 0);
                        path.close();
                    } else {
                        path.moveTo(0, 0);
                        path.lineTo(0, height - arcHeight);
                        path.quadTo(width / 2, height + arcHeight, width, height - arcHeight);
                        path.lineTo(width, 0);
                        path.close();
                    }
                    break;

                case ArcLayoutSettings.POSITION_TOP_CURVE:
                    if (settings.isCropInside()) {
                        path.moveTo(0, height);
                        path.lineTo(0, 0);
                        path.quadTo(width / 2, 2 * arcHeight, width, 0);
                        path.lineTo(width, height);
                        path.close();
                    } else {
                        path.moveTo(0, arcHeight);
                        path.quadTo(width / 2, -arcHeight, width, arcHeight);
                        path.lineTo(width, height);
                        path.lineTo(0, height);
                        path.close();
                    }
                    break;


                case ArcLayoutSettings.POSITION_LEFT_CURVE:
                    if (settings.isCropInside()) {
                        path.moveTo(width, 0);
                        path.lineTo(0, 0);
                        path.quadTo(arcHeight * 2, height / 2, 0, height);
                        path.lineTo(width, height);
                        path.close();
                    } else {
                        path.moveTo(width, 0);
                        path.lineTo(arcHeight, 0);
                        path.quadTo(-arcHeight, height / 2, arcHeight, height);
                        path.lineTo(width, height);
                        path.close();
                    }
                    break;
                case ArcLayoutSettings.POSITION_RIGHT_CURVE:
                    if (settings.isCropInside()) {
                        path.moveTo(0, 0);
                        path.lineTo(width, 0);
                        path.quadTo(width - arcHeight * 2, height / 2, width, height);
                        path.lineTo(0, height);
                        path.close();
                    } else {
                        path.moveTo(0, 0);
                        path.lineTo(width - arcHeight, 0);
                        path.quadTo(width + arcHeight, height / 2, width - arcHeight, height);
                        path.lineTo(0, height);
                        path.close();
                    }
                    break;

            }

            return path;
        }


        @Override
        protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
            super.onLayout(changed, left, top, right, bottom);
            if (changed) {
                calculateLayout();
            }
        }

        private void calculateLayout() {
            if (settings == null) {
                return;
            }
            height = getMeasuredHeight();
            width = getMeasuredWidth();

            if (radius > 0 && settings.getRounded_corn_pos() != ArcLayoutSettings.POSITION_DEFAULT) {
                clipPathOne = roundedCornerPath(radius, settings.getRounded_corn_pos());
            }

            if (settings.getArc_position() != ArcLayoutSettings.POSITION_DEFAULT) {


                if (width > 0 && height > 0) {
                    if (settings.getArc_position() == ArcLayoutSettings.POSITION_BOTH_CURVE) {
                        clipPathOneCurv = createClipPath(ArcLayoutSettings.POSITION_TOP_CURVE);
                        clipPathTwoCurv = createClipPath(ArcLayoutSettings.POSITION_BOTTOM_CURVE);
                    } else {
                        clipPathOneCurv = createClipPath(settings.getArc_position());
                    }

                    ViewCompat.setElevation(this, settings.getElevation());
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && !settings.isCropInside()) {
                        ViewCompat.setElevation(this, settings.getElevation());
                        setOutlineProvider(new ViewOutlineProvider() {
                            @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
                            @Override
                            public void getOutline(View view, Outline outline) {
                                if (settings.getArc_position() == ArcLayoutSettings.POSITION_BOTH_CURVE) {
                                    outline.setConvexPath(clipPathOneCurv);
                                    outline.setConvexPath(clipPathTwoCurv);
                                } else {
                                    //outline.setConvexPath(clipPathOneCurv);
                                }
                            }
                        });
                    }
                }

            }
        }


        @Override
        protected void dispatchDraw(Canvas canvas) {
            Paint paint = new Paint();
            paint.setAntiAlias(true);
            paint.setColor(Color.WHITE);

            int saveCount = canvas.saveLayer(0, 0, getWidth(), getHeight(), null, Canvas.ALL_SAVE_FLAG);
            super.dispatchDraw(canvas);
            paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY));

            if (clipPathOneCurv != null) {
                canvas.drawPath(clipPathOneCurv, paint);
            }
            if (clipPathTwoCurv != null) {
                canvas.drawPath(clipPathTwoCurv, paint);
            }
            if (clipPathOne != null) {
                canvas.drawPath(clipPathOne, paint);
            }


            canvas.restoreToCount(saveCount);


        }


        private Path roundedCornerPath(float cornerRadius, int position) {
            //path.rewind();
            Path path = new Path();
            final int width = getWidth();
            final int height = getHeight();
            final float twoRadius = cornerRadius * 2;
            cornerRect.set(-cornerRadius, -cornerRadius, cornerRadius, cornerRadius);

            if (position == ArcLayoutSettings.POSITION_TOP_LEFT_ROUND || position == ArcLayoutSettings.POSITION_TOP_ROUND || position == ArcLayoutSettings.POSITION_ALL_ROUND) {
                cornerRect.offsetTo(0f, settings.getArcHeight());
                path.arcTo(cornerRect, 180f, 90f);
            } else {
                path.moveTo(0f, 0f);
            }

            if (position == ArcLayoutSettings.POSITION_TOP_RIGHT_ROUND || position == ArcLayoutSettings.POSITION_TOP_ROUND || position == ArcLayoutSettings.POSITION_ALL_ROUND) {
                cornerRect.offsetTo(width - twoRadius, settings.getArcHeight());
                path.arcTo(cornerRect, 270f, 90f);
            } else {
                path.lineTo(width, 0f);
            }

            if (position == ArcLayoutSettings.POSITION_BOTTOM_RIGHT_ROUND || position == ArcLayoutSettings.POSITION_BOTTOM_ROUND || position == ArcLayoutSettings.POSITION_ALL_ROUND) {
                cornerRect.offsetTo(width - twoRadius, height - twoRadius);
                path.arcTo(cornerRect, 0f, 90f);
            } else {
                path.lineTo(width, height);
            }

            if (position == ArcLayoutSettings.POSITION_BOTTOM_LEFT_ROUND || position == ArcLayoutSettings.POSITION_BOTTOM_ROUND || position == ArcLayoutSettings.POSITION_ALL_ROUND) {
                cornerRect.offsetTo(0f, height - twoRadius);
                path.arcTo(cornerRect, 90f, 90f);
            } else {
                path.lineTo(0f, height);
            }

            path.close();
            return path;
        }

    }
导入android.content.Context;
导入android.graphics.Canvas;
导入android.graphics.Color;
导入android.graphics.Outline;
导入android.graphics.Paint;
导入android.graphics.Path;
导入android.graphics.PorterDuff;
导入android.graphics.PorterDuffXfermode;
导入android.graphics.RectF;
导入android.os.Build;
导入android.support.annotation.RequiresApi;
导入android.support.v4.view.ViewCompat;
导入android.util.AttributeSet;
导入android.view.view;
导入android.view.ViewOutlineProvider;
导入android.widget.FrameLayout;
公共类ArcLayout扩展了FrameLayout{
专用ArcLayoutSettings设置;
私有整数高度=0;
私有整数宽度=0;
专用路径clipPathOne;
专用路径clipPathOneCurv;
专用路径clipPathTwoCurv;
专用浮动半径=0,边距=0;
private final RectF cornerRect=新RectF();
公共ArcLayout(上下文){
超级(上下文);
init(上下文,null);
}
公共ArcLayout(上下文、属性集属性){
超级(上下文,attrs);
init(上下文,attrs);
}
公共void init(上下文、属性集属性){
设置=新的ArcLayoutSettings(上下文、属性);
settings.setElevation(viewcompt.getElevation(this));
radius=settings.getRadius();
margin=settings.getMargin();
/**
*如果硬件加速打开(API 14中的默认设置),clipPathOne工作正常
*来自API 18。
*
*因此,如果API小于18,我们将禁用硬件加速
*
* https://developer.android.com/guide/topics/graphics/hardware-accel.html#unsupported
*第#节不支持的绘图操作
*/
if(Build.VERSION.SDK\u INT<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_centerInParent="true"
    android:background="@color/colorPrimaryDark"
    android:gravity="center">


        <com.example.sonalsb.curved_img.ArcLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:arc_cropDirection="cropOutside"
            app:corner_position="top"
            app:corner_radius="12dp"
            app:arc_position="top"
            app:arc_height="8dp">


            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_horizontal|bottom"
                android:adjustViewBounds="true"
                android:src="@drawable/cartoon" />

        </com.example.sonalsb.curved_img.ArcLayout>


</RelativeLayout>
 <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <declare-styleable name="ArcLayout">

            <attr name="arc_height" format="dimension" />

            <attr name="corner_radius" format="dimension"/>

            <attr name="corner_margin" format="dimension"/>

            <attr name="corner_position">
                <enum name="top_left" value="0"/>
                <enum name="top_right" value="1"/>
                <enum name="bottom_left" value="2"/>
                <enum name="bottom_right" value="3"/>

                <enum name="top" value="4"/>
                <enum name="bottom" value="5"/>
                <enum name="left" value="6"/>
                <enum name="right" value="7"/>

                <enum name="empty" value="9"/>
                <enum name="all" value="10"/>
            </attr>

            <attr name="arc_position">
                <enum name="bottom" value="0"/>
                <enum name="top" value="1"/>
                <enum name="left" value="2"/>
                <enum name="right" value="3"/>
                <enum name="both" value="4"/>

                <enum name="empty" value="99"/>
            </attr>
            <attr name="arc_cropDirection" format="enum">
                <enum name="cropInside" value="0" />
                <enum name="cropOutside" value="1"/>
            </attr>
        </declare-styleable>
    </resources>