精华内容
下载资源
问答
  • 2021-08-20 00:43:42

    点击上方码农的后花园”,选择星标” 公众号

    精选文章,第一时间送达

    基于python使用OpenCV实现在一张图片中检测出圆形,并且根据圆检测结果信息,绘制 标记出圆的边界和圆心。

    1 HoughCircles 霍夫圆检测函数

    在Opencv中使用HoughCircles函数可以实现圆的检测,具体函数参数如下:

    • image: 输入图像,8位灰度单通道图像

    • method: 检测圆的方法,目前OpenCV中有HOUGH_GRADIENTHOUGH_GRADIENT_ALT两种方法。

    • dp: 检测圆心的累加器图像的分辨率与输入图像之比的倒数,如果dp= 1时,累加器和输入图像具有相同的分辨率。如果dp=2,累加器输入图像便有输入图像一半那么大的宽度和高度。减少图像的分辨率(宽高变小)是为了减少计算量,一般默认为1就好,保持原有图像精度。

    • minDist: 检测到的两个圆心之间的最小距离。如果参数太小,除了真实的一个圆圈之外,可能错误地检测到多个相邻的圆圈。如果太大,可能会遗漏一些圆圈。

    • circles: 检测到的圆的信息输出向量(x,y,r),分别代表检测到圆的中心坐标和圆半径。

    • param1: Canny 边缘检测的高阈值,低阈值被自动置为高阈值的一半,默认为 100。也就是说检测图像中像素点的值大于param1是会检测为边缘。

    • param2: 表示在检测阶段圆心的累加器阈值。它越小的话,会误检测到更多根本不存在的小圆,而越大,能通过检测的圆就更加接近完美的圆形了。

    • minRadius: 表示图像中能检测到最小圆的半径的值。

    • maxRadius: 表示图像中检测到的圆的最大半径的值。

    参数设置总结

    • param2值的设置根据要检测图像中圆的大小进行设置,minRadius最小圆半径和maxRadius最大圆半径可以辅助我们更好选择圆,如果没有特殊需要就都默认为0。minDist可以帮助我们筛选掉检测相近的圆。

    • 霍夫圆检测的原理:第一步通过Canny边缘检测算法检测边缘,发现可能的圆心,然后再计算边缘像素点到圆心的距离估计圆的半径。

    2 HoughCircles 霍夫圆检测代码实现

    实现霍夫圆检测的实现代码非常简单,首先使用cv2.cvtColor函数将要检测的图像转换为灰度图像,然后调用cv2.HoughCircles霍夫圆检测函数进行检测,检测返回所有圆的中心坐标和半径信息向量circles(x,y,r)

    注意: 霍夫圆检测对噪声比较敏感,所以进行霍夫圆检测的之前可以先进行中值滤波cv2.medianBlur

    def circle_detect(image):
        # 灰度化
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        # 输出图像大小,方便根据图像大小调节minRadius和maxRadius
        print(image.shape)
        # 进行中值滤波
        img = cv2.medianBlur(gray, 5)
    
        # 霍夫变换圆检测
        circles = cv2.HoughCircles(img, cv2.HOUGH_GRADIENT, 1, 50, param1=100, param2=30, minRadius=5, maxRadius=100)
        for circle in circles[0]:
            # 圆的基本信息
            print(circle[2])
            # 坐标行列-圆心坐标
            x = int(circle[0])
            y = int(circle[1])
            # 半径
            r = int(circle[2])
            # 在原图用指定颜色标记出圆的边界
            cv2.circle(image, (x, y), r, (0, 0, 255), 3)
            # 画出圆的圆心
            cv2.circle(image, (x, y),5, (0, 255, 0), -1)
    
        cv2.imshow("image",image)
    
    img = cv2.imread(r'D:\yolov5-5.0\data\images\1.jpg')
    circle_detect(image=img)
    
    cv2.waitKey(0)
    

    最后再借助OpenCV中的画圆函数cv2.circle,cv2.circle函数参数具体如下:

    • img: 要在其上绘制圆的输入图像

    • center: 绘制圆的中心坐标(x,y),未设置shift参数时,默认为整数int类型。

    • radius: 绘制圆的半径,未设置shift参数时,默认为整数int类型

    • color: 绘制圆的边界线的颜色,OpenCV读取图像后,图像格式为BGR,即【0,255,255】表示用红色绘制圆的边缘。

    • thickness: 圆的边界线的粗细像素值。值为负(-1)时绘制实心圆。

    • lineType: 可选参数,线的类型:虚线、实线

    • shift: 可选参数,圆心坐标点和半径值的小数点位数。

    3 检测效果

    通过合理的控制minDistminRadiusmaxRadiusparam2这四个参数的值,最终的检测效果如下图:

    公众号:码农的后花园,后台回复:项目实战,即可获取代码下载使用。

    往期精彩教你用OpenCV 和 Python给证件照换底色(蓝底 <->红底->白底) &&    教你用OpenCV和Python实现手掌检测和手掌计数

                                                     分享给更多朋友,转发,点赞,在看

    更多相关内容
  • 最近的小程序项目个设计图要求做一...于是我决定做个动态! 在mdn把新特性gradients(渐变)、transitions(过渡)、 animations(动画) 都看了一遍,不禁感叹css牛逼!这三个新特性加上canvas,仿佛一瞬间了正面刚js...

    最近的小程序项目有个设计图要求做一个圆环,两种颜色分配,分别代表可用金额和冻结金额。要是就直接这么显示,感觉好像挺没水平??于是我决定做个动态!

    在mdn把新特性gradients(渐变)、transitions(过渡)、 animations(动画) 都看了一遍,不禁感叹css牛逼!这三个新特性加上canvas,仿佛一瞬间有了正面刚js的能耐。用js很难过渡得那么完美,而且浏览器的css渲染明显比用js性能好得多。
    然后看了张鑫旭(传说中玩转css的那个男人)的一篇关于圆环的博文,拍案叫绝。链接=>3种纯CSS实现中间镂空的12色彩虹渐变圆环方法
    只能说服气!除了灵活运用各种css特性之外,鑫大佬最让我佩服的是他的创造性思维。会让你不禁感叹:卧槽,还有这种操作?!想到了高中物理老师每次装完逼讲的一句话:思想有多远,就能走多远。

    虽然demo跟我的需求不太一样,问题还是没有解决,但我认真看完之后还是学会了很多,对我后面的代码帮助很大。鑫大佬这篇博文的重点还是在渐变,而我需要动态平缓连续得实现颜色的分配,比如原本整个环是绿色,然后慢慢地60%被红色占了,而且整个过程要平滑。跟我的需求最接近的就是倒计时那个demo,linear-gradient线性渐变实现的多彩圆环demo,但不是连续的过程,而是通过剪裁,每次剪30度。

    看了其他一些博客分享,好像也没有找到合适的,那没办法了...只能自己想一个!
    因为再写这个demo的时候,发现小程序和H5在css表现上还是有些差异(具体有哪些差异,在文末总结),所以还是贴H5代码好了。

    不多说,直接上代码


    代码部分

    //html部分
    <div class="circle">
      <div class="circle-left"></div>
      <div class="circle-right"></div>
      <div class="circle-bottom-left"></div>
      <div class="circle-bottom-right"></div>
    </div>
    <div class="info">¥4500/¥5000</div>
    //css部分
    .circle {
      -webkit-mask: radial-gradient(transparent 150px, #000 150px);
      width: 400px;
      height: 400px;
      overflow: hidden;
      border-radius: 50%;
      position: relative;
    }
    
    .circle-left {
      width: 50%;
      height: 100%;
      background: #24B39B;
      transform-origin: 100% 50%;
      position: absolute;
      left: 0;
      z-index: 0;
    }
    
    .circle-right {
      width: 50%;
      height: 100%;
      background: #24B39B;
      transition: transform 1s linear;
      transform-origin: 0% 50%;
      position: absolute;
      right: 0;
      z-index: 2;
    }
    
    .circle-bottom-left {
      width: 50%;
      height: 100%;
      background: rgb(234, 67, 15);
      position: absolute;
      left: 0;
      z-index: -1;
    }
    
    .circle-bottom-right {
      width: 50%;
      height: 100%;
      background: rgb(234, 67, 15);
      position: absolute;
      right: 0;
      z-index: 1;
    }
    
    .info {
      width: 400px;
      height: 400px;
      line-height: 400px;
      text-align: center;
      margin-top: -400px;  
    }
    //js代码
    window.onload = function () {
      var red = 4500, total = 5000 //红色区域代表的金额和总金额
      var percent = red / total
      var right = document.getElementsByClassName('circle-right')[0]
      var left = document.getElementsByClassName('circle-left')[0]
      if (percent <= 0.5) {  //红色区域不超过一半
        right.style.transform = `rotate(${percent * 360}deg)`
      } else {    //红色区域超过一半的情况,重点部分
        right.style.transform = `rotate(180deg)`
        right.style.transition = `opacity 0s step-end 1s, transform 1s linear` //timing-function需要设为linear来达到视觉上的平缓过渡
        right.style.opacity = 0
    
        left.style.transition = `transform ${(percent - 0.5) / 0.5}s linear 1s`
        left.style.transform = `rotate(${percent * 360 - 180}deg)`
      }
    }

    效果图
    图片描述

    思路

    st=>start: 开始
    e=>end: 结束
    con=>condition: degree<=180?
    op1=>operation: 右绿旋转
    op2=>operation: 右绿旋转180度,opacity变为0,然后左绿旋转
    
    st->con
    con(yes)->op1->e
    con(no)->op2->e

    难点在于红色区域大于一半的情况,左右绿色半圆的衔接,过渡要自然,不能让人看出什么明显的破绽。
    **这种情况我的做法是:4个半圆(红绿各两个)的z-index设为左红<左绿<右红<右绿
    两个绿半圆的transform的time-function(时间函数)统一设为linear(线性)。右绿旋转180度(1秒)后opacity立即变成0(时间函数step-end),这样就不会挡住左红露出。然后左绿开始转(transform延迟1秒执行,因为要等待右绿转完),它转的时间要根据度数动态控制,比如总共要转270度,右绿转了180度,所以左绿只需要转90度。这就好办了,为了保持右绿的旋转速度,时间和度数要成比例,右绿转180度用1s,左绿转90度只能用0.5s

    优点

    1. 不需要js代码动态实现动画(js只用来计算度数和触发transition)
    2. 因为对js几乎没什么依赖,浏览器内核直接渲染,性能较好,过渡自然
    3. 代码量很少
    

    不足

    1. 因为是css3的属性,兼容不会太好
    2. 时间函数只能用线性linear,用默认的ease(不匀速)会衔接不上
    3. 只能两种颜色分布,再加一种的话行不通
    

    有更好办法实现相同效果的大佬,欢迎留言!

    问题探究&解决

    虽然效果图gif画质有点感人,但还是可以发现一个问题:内环边缘明显很粗糙!这个要怎么解决呢?
    中间这个透明遮罩的代码是`-webkit-mask: radial-gradient(transparent 150px, #000 150px);
    我的做法就是把transparent 150px改成transparent 148px,就是说空出一两个像素点,让粗糙的部分虚化。
    至于为什么会出现粗糙,额。。。我觉得是150px这一层上了太多颜色,加上本来画弧圈就没有防锯齿处理,色素点可能会拥挤,加剧了锯齿状这种效果。具体是什么原因,或者有更好的解决办法,欢迎大佬指教。

    修改后的效果图
    图片描述
    是不是明显好很多~

    上文提到的小程序的css和h5的差异,经过再一次的实验,发现不是小程序内核渲染的问题,应该是微信开发者工具显示的问题。。。希望尽快能得到改善,不然对开发人员影响挺大的

    clipboard.png这个info的盒子margin-top负数在工具中显示翻不上去,但内容50000上去了.
    clipboard.png过了几秒再点(啥都没干),这个info的盒子又跑到这里来

    clipboard.png为了验证这个info的盒子到底有没有上去,我加了一个红色的盒子,发现并没有被info盒子挤掉

    clipboard.png取消info的margin-top属性,红色的盒子被挤掉,内容50000也下来了

    终于!!!原来都是开发者工具摆的乌龙,其实info盒子一直在上面,只是调试不能正常显示他的位置。。。

    话说回来,小程序不能获取DOM节点操作DOM,突然觉得只能数据驱动,不能操作DOM节点有时也挺麻烦的,transition那些需要动态改的样式只能写到style了。。。

    最后,看好小程序,希望各种问题能尽快完善,越来越好。

    展开全文
  • 原文出处:拓端数据部落公众号 填充Circle packing算法 已经开发了大量确定性和随机性的填充算法。... RepelLayout通过成对排斥迭代移动圆圈来搜索非重叠布局。... ProgressiveLayout连续放置,使...

    原文链接:http://tecdat.cn/?p=24658 

    原文出处:拓端数据部落公众号

    圆填充Circle packing算法

    已经开发了大量确定性和随机性的圆填充算法。

    • RepelLayout 通过成对排斥迭代移动圆圈来搜索非重叠布局。圆的位置被限制在一个矩形区域内。为避免边缘效应,可以将边界区域视为环面,例如,推到左侧边缘的圆将重新进入右侧边缘的边界区域。这是一种非常简单且效率相当低的算法,但通常会产生良好的结果。

    • ProgressiveLayout 连续放置圆,使每个圆与先前放置的两个圆在外部相切。该算法是确定性的,尽管可以通过改变输入圆圈的顺序产生不同的布局。它非常高效,因此适用于处理大型数据集。 

    • GraphLayout 试图找到满足输入邻接图的安排。实现是实验性的。 

    第一个例子

    我们将首先创建一组不同大小的圆,然后找到可以用 ggplot 显示的非重叠排列。

    首先,我们创建一组随机圆,位于边界正方形的中心部分,较小的圆比较大的圆更常见。我们将圆的大小表示为面积。 

    
    as <- reta(rcs ,5) * maxaa

    接下来,我们尝试找到一个不重叠的排列,允许圆圈占据边界正方形的任何部分。返回值是一个包含布局元素和执行迭代次数的列表。

    
    Layout(areass)
    
    

    布局作为具有圆心坐标和半径的数据框返回。

    head( layout )

    我们将其转换为圆形顶点的数据集,用 ggplot 显示。

    结果数据集有一个整数 id 字段,它对应于传递给 的原始数据中圆圈的位置。

    
    head(dtg)

    现在我们可以绘制布局了。

    
    themebw() 
    
    thest(t)
    ggplot(daa = d.g)

     基于图的圆填充

    圆填充的另一种方法是从指定圆的大小和相切(即哪些圆接触哪些其他圆)开始,然后搜索满足此要求的排列。

    在下图中,左侧的图形表示所需的圆相切模式。圆 5、7、8 和 9 是 内部的,而其余​​圆圈是 外部的。右边的圆填充显示了符合输入图的圆圈排列。


    切线图和结果堆积

    GraphLayout 实现了算法的基本版本。下面的例子产生一个类似于上图的布局:

    
    
    ## 切线列表。矢量元素是圆 ID。
    ##每个向量的第一个元素是一个内圆
    ## 和随后的元素是它的邻居。
    
    
    ## 外圆半径。
    data.frame(id )
    
    ## Layout 函数用于查找排列
    ##与`internal`指定的切线相对应的圆
    ## 和由 `external` 指定的外圆尺寸。结果是一个四列的 data.frame: id, x, y, radi。
    ##
     circleGraphLayout 
    
    ## 获取圆顶点的数据
     LayotVtics(laout,xyizcs = 2:4, dl = 1)
    ## 绘制带有 ID 注释的圆圈。
    ggplot() +
      geom_olon()+
      
      ge_tet(data=ayo) +
      
      oal() 

    指定初始圆位置

    在前面的示例中,我们将圆大小的向量传递给 circleRepelLayout,该函数通过将圆放置在靠近边界区域中心的位置,为圆随机分配起始位置。或者,我们可以预先指定初始位置。为了说明这一点,我们首先将所有圆圈放置在边界区域的一个角附近。

    
    
    lLayout(dt.nt)
    
    

    接下来我们使用 ggplot 显示初始和最终布局。请注意,在我们的初始布局中,我们将圆的大小表示为面积,因此我们需要在调用Vertices 函数时指定 ,否则它假定大小是半径。

    
    # 获取初始布局的顶点数据,其中大小是区域
    dgil - ciLocs(dt., sieye = "area")
    # 获取函数返回的布局的顶点数据 whre
    # 尺寸是半径
    a..i <- ciaoees(rlyout)
    
    
    ggplot(data
       ge_pgon(couaa=0.3) +
      
       cor_el(xli=lis yl=imts) 

    移动和固定

    RepelLayout 函数接受一个可选 weights 参数,以在布局算法的每次迭代中对圆的移动进行额外控制。该参数采用一个数值向量,其值在 0-1 范围内(此范围之外的任何值都将被限制为 0 或 1)。权重为 0 可防止圆完全移动,而权重为 1 则允许完全移动。

    为了说明这一点,我们将从更早使用的数据集中选择几个圆圈,将它们放大并通过将它们的权重设置为 0.0 来固定它们的位置。

    
    # 选择几个任意的圆圈
    
    dai$ea[las] <- 2 * axa
    
    # 重新生成初始圆的顶点数据,添加一列
    # 表示一个圆是固定的还是自由的
    dnta <- cres(dain, ste = "area")
    
    dani$sae <- iflse(dtgtd %in% laid, "fixed", "free")
    
    # 现在使用权重向量重新运行布局算法以固定位置
    # 最大的圆
    
    res <- cirtt.t
    
    dgfal <- circes(es$aut)
    
    
    plot(dta = da,as(x, y, grp=d, fl=ste)) +
      
      gen(coor) 
    
    

    请注意,在初始布局中重叠的固定圆在最终布局中仍然重叠。


    最受欢迎的见解

    1.R语言动态图可视化:如何、创建具有精美动画的图

    2.R语言生存分析可视化分析

    3.Python数据可视化-seaborn Iris鸢尾花数据

    4.r语言对布丰投针(蒲丰投针)实验进行模拟和动态

    5.R语言生存分析数据分析可视化案例

    6.r语言数据可视化分析案例:探索brfss数据数据分析

    7.R语言动态可视化:制作历史全球平均温度的累积动态折线图动画gif视频图

    8.R语言高维数据的主成分pca、 t-SNE算法降维与可视化分析案例报告

    9.python主题LDA建模和t-SNE可视化

    展开全文
  • 轮播图,可以手动滑动,可以自动播放滑动,带圆点指示器,可以动态添加图片,下载积分终于可以修改编辑了,
  • Android 布局圆角方案总结

    万次阅读 多人点赞 2020-06-09 23:57:04
    这里和图片切圆角一些雷同的地方,可以相互借鉴,但是也不不全一样。图片切圆角的一些总结和实践准备下次有空再写出来。 假设我们要对一种LinearLayout布局切圆角,不知道你能想出来哪些办法。我这里先提供下我...

    一.遇到的问题

        最近在开发中会遇到Android布局切圆角的需求,大多数是对一个layout布局切下圆角。这里和图片切圆角有一些雷同的地方,可以相互借鉴,但是也不全一样。图片切圆角的一些总结和实践准备下次有空再写出来。

        假设我们要对一种LinearLayout布局切圆角,不知道你能想出来哪些办法。我这里先提供下我的思路,亲自实践过的主要包括下面五种:

       1.利用xml背景文件配置shape属性实现切圆角

       2.利用GradientDrawable实现切圆角

       3.利用clipPath实现切圆角

       4.利用CardView实现切圆角

        5.利用ViewOutlineProvider实现切圆角

    下面分别对这几种方式进行实践与优缺点分析,原理讲解较少,感兴趣可以自己再深入了解下。

     

    二.利用xml背景文件配置shape属性实现

    2.1方案实现

        这种方式相比大家都比较熟悉了,就是在drawable文件夹下新建一个App Action XML File,然后作为background属性添加到Layout XML File中。

        如果要生成四个角都为10dp圆角的形状我们可以在drawable文件夹下新建如下shape_10dp_corners.xml文件

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">
        <corners android:radius="10dp" />
        <solid android:color="@color/colorAccent" />
    </shape>

        如果仅要生成上方两个10dp圆角的形状我们可以在drawable文件夹下新建如下shape_10dp_top_corners.xml文件

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">
        <solid android:color="@color/colorPrimary"/>
        <corners
            android:topLeftRadius="10dp"
            android:topRightRadius="10dp" />
    </shape>

        如果仅要生成上方两个10dp圆角的形状我们可以在drawable文件夹下新建如下shape_10dp_bottom_right_corners.xml文件

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">
        <corners android:bottomRightRadius="10dp"/>
        <solid android:color="@color/colorAccent"/>
    </shape>

        然后在XmlShapeActivity的布局XML文件中为对应的三个LinearLayout分别设置background属性如下

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".xmlshape.XmlShapeActivity">
    
        <LinearLayout
            android:id="@+id/lly1"
            android:layout_width="0dp"
            android:layout_height="100dp"
            android:layout_marginStart="16dp"
            android:layout_marginLeft="16dp"
            android:layout_marginTop="16dp"
            android:layout_marginEnd="16dp"
            android:layout_marginRight="16dp"
            android:background="@drawable/shape_10dp_corners"
            android:orientation="vertical"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent">
    
            <TextView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:gravity="center"
                android:text="四个圆角10dp"
                android:textSize="24sp"
                android:textColor="#FFFFFF" />
        </LinearLayout>
    
        <LinearLayout
            android:id="@+id/lly2"
            android:layout_width="0dp"
            android:layout_height="100dp"
            android:layout_marginStart="16dp"
            android:layout_marginLeft="16dp"
            android:layout_marginTop="16dp"
            android:layout_marginEnd="16dp"
            android:layout_marginRight="16dp"
            android:background="@drawable/shape_10dp_top_corners"
            android:orientation="vertical"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/lly1" >
            <TextView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:gravity="center"
                android:text="上方圆角10dp"
                android:textSize="24sp"
                android:textColor="#FFFFFF"/>
        </LinearLayout>
    
        <LinearLayout
            android:id="@+id/lly3"
            android:layout_width="0dp"
            android:layout_height="100dp"
            android:layout_marginStart="16dp"
            android:layout_marginLeft="16dp"
            android:layout_marginTop="16dp"
            android:layout_marginEnd="16dp"
            android:layout_marginRight="16dp"
            android:background="@drawable/shape_10dp_bottom_right_corners"
            android:orientation="vertical"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/lly2" >
            <TextView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:gravity="center"
                android:text="右下圆角10dp"
                android:textSize="24sp"
                android:textColor="#FFFFFF"/>
        </LinearLayout>
    </androidx.constraintlayout.widget.ConstraintLayout>

        然后勉为其难地贴一下打酱油的XmlShapeActivity代码

    package com.openld.roundcornerdemmo.xmlshape;
    
    import androidx.appcompat.app.AppCompatActivity;
    
    import android.os.Bundle;
    
    import com.openld.roundcornerdemmo.R;
    
    public class XmlShapeActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_xml_shape);
        }
    }

    2.1运行效果

    2.3优缺点

    优点:

    1.最简单

    2.四个圆角可以单独定制,也可以统一处理

    3.还可以一并设置背景颜色等属性

    4.圆角无锯齿

     

    缺点:

    1.圆角属性是提前确定的并写在客户端本地的drawable中,如果是动态下发再去配置的话这种方式无法支持。

    2.如果子View长宽都match_parent并且设置一个有色background属性的话,圆角就消失了。

     

    三.利用GradientDrawable实现切圆角

    3.1 方案实现

        有没有想过动态地在Java代码中为layout设置圆角,那就想到了GradientDrawable。其实是和第一种XML方式呼应的,只不过没有办法让你你动态去配置XML,那就用GradientDrawable吧,XML shape中能设置的属性这里也能哦!

        这里先贴一下GradientDrawableActivity的布局XML

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".gradientdrawable.GradientDrawableActivity">
    
        <LinearLayout
            android:id="@+id/lly1"
            android:layout_width="0dp"
            android:layout_height="100dp"
            android:layout_marginStart="16dp"
            android:layout_marginLeft="16dp"
            android:layout_marginTop="16dp"
            android:layout_marginEnd="16dp"
            android:layout_marginRight="16dp"
            android:orientation="vertical"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent">
    
            <TextView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:gravity="center"
                android:text="四个圆角10dp"
                android:textSize="24sp" />
        </LinearLayout>
    
        <LinearLayout
            android:id="@+id/lly2"
            android:layout_width="0dp"
            android:layout_height="100dp"
            android:layout_marginStart="16dp"
            android:layout_marginLeft="16dp"
            android:layout_marginTop="16dp"
            android:layout_marginEnd="16dp"
            android:layout_marginRight="16dp"
            android:orientation="vertical"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/lly1">
    
            <TextView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:gravity="center"
                android:text="左边两个10dp圆角"
                android:textSize="24sp" />
        </LinearLayout>
    
        <LinearLayout
            android:id="@+id/lly3"
            android:layout_width="0dp"
            android:layout_height="100dp"
            android:layout_marginStart="16dp"
            android:layout_marginLeft="16dp"
            android:layout_marginTop="16dp"
            android:layout_marginEnd="16dp"
            android:layout_marginRight="16dp"
            android:orientation="vertical"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/lly2">
    
            <TextView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:gravity="center"
                android:text="左上角10dp圆角"
                android:textSize="24sp" />
        </LinearLayout>
    </androidx.constraintlayout.widget.ConstraintLayout>

        再贴一下GradientDrawableActivity的代码

    package com.openld.roundcornerdemmo.gradientdrawable;
    
    import android.graphics.drawable.GradientDrawable;
    import android.os.Bundle;
    import android.widget.LinearLayout;
    
    import androidx.appcompat.app.AppCompatActivity;
    
    import com.openld.roundcornerdemmo.R;
    import com.openld.roundcornerdemmo.utils.DisplayUtils;
    
    public class GradientDrawableActivity extends AppCompatActivity {
        private LinearLayout mLly1;
    
        private LinearLayout mLly2;
    
        private LinearLayout mLly3;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_gradient_drawable);
    
            initWidgets();
        }
    
        private void initWidgets() {
            mLly1 = findViewById(R.id.lly1);
            GradientDrawable gradientDrawable1 = new GradientDrawable();
            gradientDrawable1.setShape(GradientDrawable.RECTANGLE);
            gradientDrawable1.setCornerRadius(DisplayUtils.dp2px(this, 10F));
            gradientDrawable1.setColor(getResources().getColor(R.color.colorPrimary));
            mLly1.setBackground(gradientDrawable1);
    
            mLly2 = findViewById(R.id.lly2);
            GradientDrawable gradientDrawable2 = new GradientDrawable();
            gradientDrawable2.setShape(GradientDrawable.RECTANGLE);
            gradientDrawable2.setColor(getResources().getColor(R.color.colorAccent));
            float[] radii = new float[]{
                    DisplayUtils.dp2px(this, 10F), DisplayUtils.dp2px(this, 10F),
                    0F, 0F,
                    0F, 0F,
                    DisplayUtils.dp2px(this, 10F), DisplayUtils.dp2px(this, 10F)
            };
            gradientDrawable2.setCornerRadii(radii);
            mLly2.setBackground(gradientDrawable2);
    
            mLly3 = findViewById(R.id.lly3);
            GradientDrawable gradientDrawable3 = new GradientDrawable();
            gradientDrawable3.setShape(GradientDrawable.RECTANGLE);
            gradientDrawable3.setColor(getResources().getColor(R.color.colorPrimary));
            float[] radii1 = new float[]{
                    DisplayUtils.dp2px(this, 10F), DisplayUtils.dp2px(this, 10F),
                    0F, 0F,
                    0F, 0F,
                    0F, 0F
            };
            gradientDrawable3.setCornerRadii(radii1);
            mLly3.setBackground(gradientDrawable3);
        }
    }

        核心代码都在initWidgets()方法中,里面实例化一个GradientDrawable对象,设置一下对应的属性。setCornerRadii()或者se'tCornerRadius()方法即为设置圆角,具体可以看下API,这里不再赘述。

     

    3.2 运行效果

     

    3.3 优缺点

    优点:

    1.支持动态配置啊

    2.四个圆角可以单独定制,也可以统一处理

    3.还可以一并设置背景颜色等属性

    4.圆角无锯齿

     

    缺点

    1.如果子View长宽都match_parent并且设置一个有色background属性的话,圆角就消失了。

     

    四. 利用clipPath实现切圆角

    4.1 方案实现

        继承现有的布局,在draw()方法中使用clipPath()方法切割你想要的形状,只要切割出一个圆角矩形即可。

    比如新建一个继承LinearLayout的CornersLinearLayout

    package com.openld.roundcornerdemmo.clippath;
    
    import android.content.Context;
    import android.content.res.TypedArray;
    import android.graphics.Canvas;
    import android.graphics.Path;
    import android.graphics.RectF;
    import android.util.AttributeSet;
    import android.widget.LinearLayout;
    
    import androidx.annotation.Nullable;
    
    import com.openld.roundcornerdemmo.R;
    
    /**
     * author: lllddd
     * created on: 2020/6/9 10:55
     * description:
     */
    public class CornersLinearLayout extends LinearLayout {
        private Context mContext;
    
        private float mCorners;
        private float mLeftTopCorner;
        private float mRightTopCorner;
        private float mLeftBottomCorner;
        private float mRightBottomCorner;
    
        private int mWidth;
        private int mHeight;
    
        public CornersLinearLayout(Context context) {
            this(context, null);
        }
    
        public CornersLinearLayout(Context context, @Nullable AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public CornersLinearLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
    
            mContext = context;
    
            TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CornersLinearLayout);
            mCorners = typedArray.getDimension(R.styleable.CornersLinearLayout_corner, 0F);
            mLeftTopCorner = typedArray.getDimension(R.styleable.CornersLinearLayout_leftTopCorner, 0F);
            mRightTopCorner = typedArray.getDimension(R.styleable.CornersLinearLayout_rightTopCorner, 0F);
            mRightBottomCorner = typedArray.getDimension(R.styleable.CornersLinearLayout_rightBottomCorner, 0F);
            mLeftBottomCorner = typedArray.getDimension(R.styleable.CornersLinearLayout_leftBottomCorner, 0F);
            typedArray.recycle();
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            mWidth = getMeasuredWidth();
            mHeight = getMeasuredHeight();
            setMeasuredDimension(mWidth, mHeight);
        }
    
        @Override
        public void draw(Canvas canvas) {
            canvas.save();
    
            Path path = new Path();
            RectF rectF = new RectF(0, 0, mWidth, mHeight);
            if (mCorners > 0F) {
                path.addRoundRect(rectF, mCorners, mCorners, Path.Direction.CCW);
            } else {
                float[] radii = new float[]{
                        mLeftTopCorner, mLeftTopCorner,
                        mRightTopCorner, mRightTopCorner,
                        mRightBottomCorner, mRightBottomCorner,
                        mLeftBottomCorner, mLeftBottomCorner
                };
                path.addRoundRect(rectF, radii, Path.Direction.CCW);
            }
            canvas.clipPath(path);
    
            super.draw(canvas);
        }
    }
    

        相关的属性声明在style.xml文件中配置,这里不涉及。draw()方法是在onDraw()之前的一个方法,在这里可以使用clipPath()裁剪出一个圆角矩形轮廓。调用canvas.clipPath(path)生效,之后再执行super方法即可。

     

    4.2 运行效果

     

    4.3 优缺点

    优点:

    1.整个外层轮廓都切成圆角矩形,子View的background不会影响到圆角

    2.四个角可以单独配置也可以统一配置

     

    缺点:

    1.无法抗锯齿,在一些老的手机上面效果可能差强人意

    2.需要实现自己的自定义布局

     

    五.利用CardView实现切圆角

    5.1 方案实现

        CardView是v7包中的组件(ViewGroup),主要用来设置布局的边框为圆角、z轴的偏移量(这个是5.0以后才有的概念,也就是阴影的效果)。这里我们仅仅使用圆角功能。

        实现一个带CardView的布局

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".cardview.CardViewActivity">
    
        <androidx.cardview.widget.CardView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginStart="16dp"
            android:layout_marginLeft="16dp"
            android:layout_marginTop="16dp"
            android:layout_marginEnd="16dp"
            android:layout_marginRight="16dp"
            android:layout_marginBottom="16dp"
            app:cardBackgroundColor="@color/colorAccent"
            app:cardCornerRadius="10dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent">
    
            <TextView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:gravity="center"
                android:text="10dp的圆角"
                android:textColor="#FFFFFF"
                android:textSize="24sp" />
        </androidx.cardview.widget.CardView>
    
    </androidx.constraintlayout.widget.ConstraintLayout>

        对应activity的代码就没必要贴了,XML布局中

    app:cardCornerRadius="10dp"

        即配置四个角为10dp的圆角

     

    5.2 运行效果

     

    5.3 优缺点

    优点:

    1.Google的控件,效果和稳定性都是杠杠的,还支持阴影等其他的配置

    2.抗锯齿

     

    缺点:

    1.四个角要一起配置,不支持其中若干个角单独配置

    2.使用时外层要嵌套CardView

     

    六.利用ViewOutlineProvider实现切圆角

    6.1 方案实现

        利用ViewOutlineProvider设置轮廓切圆角。

        对应ViewOutlineProviderActivity的布局XML如下

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".viewoutlineprovider.ViewOutlineProviderActivity">
    
        <LinearLayout
            android:id="@+id/lly"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_marginStart="16dp"
            android:layout_marginLeft="16dp"
            android:layout_marginTop="16dp"
            android:layout_marginEnd="16dp"
            android:layout_marginRight="16dp"
            android:layout_marginBottom="16dp"
            android:orientation="vertical"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            android:background="@color/colorAccent">
    
            <TextView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:gravity="center"
                android:text="10dp的圆角"
                android:textSize="24sp" />
        </LinearLayout>
    </androidx.constraintlayout.widget.ConstraintLayout>

        ViewOutlineProviderActivity代码如下

    package com.openld.roundcornerdemmo.viewoutlineprovider;
    
    import android.graphics.Outline;
    import android.os.Build;
    import android.os.Bundle;
    import android.view.View;
    import android.view.ViewOutlineProvider;
    import android.widget.LinearLayout;
    
    import androidx.annotation.RequiresApi;
    import androidx.appcompat.app.AppCompatActivity;
    
    import com.openld.roundcornerdemmo.R;
    import com.openld.roundcornerdemmo.utils.DisplayUtils;
    
    public class ViewOutlineProviderActivity extends AppCompatActivity {
        private LinearLayout mLly;
    
        @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_view_outline_provider);
    
            initWidgets();
        }
    
        @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
        private void initWidgets() {
            mLly = findViewById(R.id.lly);
    
            mLly.setOutlineProvider(new ViewOutlineProvider() {
                @Override
                public void getOutline(View view, Outline outline) {
                    outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(), DisplayUtils.dp2px(ViewOutlineProviderActivity.this, 10F));
                }
            });
            mLly.setClipToOutline(true);
        }
    }

        关键就是mLly.setOutlineProvider()与mLly.setClipToOutline()两个方法的使用。

     

    6.2 运行效果

     

    6.3 优缺点

    优点:

    1.支持动态下发与配置

     

    缺点:

    1.只能四个角同时配置不支持每个角单独配置

     

    七.源码位置

    链接地址

     

    展开全文
  • 动态规划常见类型总结

    万次阅读 多人点赞 2019-03-26 23:55:28
    严格来说,递推不属于动态规划问题,因为动态规划不仅递推过程,还要决策(即取最优),但广义的动态规划是可以包含递推的,递推是一类简单的、特殊的动态规划,毕竟动态规划与递推密不可分。动态规划类型主要...
  • 干货分享——CAD动态

    千次阅读 2020-11-03 18:21:07
    最近同学私信问,他在CAD里画了一个圆形的法兰盘,希望在圆形的设备上打孔,根据需要,可能要均布4个或者6个圆孔。 他已经将圆孔的半径和圆孔所在的位置都用动态块来完成了,那么,能不能把这个改变均布数目的操作...
  • 自己做的小demo,效果如上图初始要求是生成整个作业的所有客观题的环形表(也就是具体几个题目不确定,每个题目几个选项不确定,都由后台数据决定,不能写死)第一步:先写出最基础的环形图代码(这里将生成环形...
  • 测试环境是在安卓手机的APP,vue的页面,也nvue的页面。如果差不多需要的同学们可以参考,也欢迎给我提出建议。(长文预警,所以这次我做了个目录给大家) 目录 一、成品效果 二、思路和写这个组件的大致...
  • 动态特性

    千次阅读 2018-05-17 10:59:34
    反之,如果程序的功能是在运行时刻才确定下来的,则称为动态特性。 动态特性是面向对象语言最强大的功能之一,因为它在语言层面上支持程序的可扩展性,而可扩展性是软件设计追求的重要目标之一。 c++虚函数、抽象...
  • 方向分布(标准差椭圆)

    千次阅读 2018-09-27 11:43:13
    点模式的分析中,一般会考察如下五种内容:   1、点的疏密,包括点数据的...5、其他,如点的一些动态变化等。 (关于点数据分析的其他详细的内容,请看虾神以前的文章,或者再公众号里面回复“点分析”)  ...
  • 区间动态规划详解

    千次阅读 多人点赞 2018-11-15 20:57:40
    前段时间遇到石子合并问题,看着题解A了,以为学会了区间DP,再次遇到能量项链这个问题的时候大脑还是一片空白,只能重新认识一下区间动态规划了。 翻过很多博客,基本上都是题解,真正对区间动态规划本身的讲解...
  • 圆环百分比分布图

    千次阅读 2017-11-14 17:04:33
    时候我们会遇到做百分比分布图的功能,这样的功能说难不难,说容易也不容易,主要是对绘制api和动画掌握的较为熟悉就行,下面就试试做下这个功能首先看个效果图:一、分析实现这个效果要做哪些事:1.画一个底部灰色...
  • 机器人局部动态避障算法dwa解析

    千次阅读 多人点赞 2019-04-30 08:55:53
    机器人局部动态避障算法dwa解析 简介   dwa算法全称叫动态窗口法(dynamic window approach),其算法过程主要分为仿真获取机器人的运动轨迹、对轨迹进行评价选择最优轨迹两个主要过程,动态窗口表达的是...
  • 最常用的UML动态

    千次阅读 2017-04-12 09:48:16
    最常用的UML动态:顺序图、活动图、状态机图。 一 顺序图 1 顺序图介绍  顺序图显示具体用例(或者是用例的一部分)的详细流程,并且显示了流程中不同对象之间的调用关系,同时还可以很详细地显示对不同...
  • 渐变圆环进度条实现

    千次阅读 2017-09-25 20:59:24
    那开始绘制我们想要的效果之前,我们一定会给我们的弧形设两个基本值,那就是弧形起点的颜色,和结尾的颜色,所以中间的哪些颜色都是根据这两个颜色进行计算得来的,好了,拿到这两个值,我们可以开始计算每个位置的...
  • 基于动态运动基元的轨迹学习方法 一、轨迹示教学习方法 1. 基于样条 基于样条的轨迹学习方法是通过样条函数拟合采集到的人体运动数据实现的,规划生成的轨迹平滑性好,但泛化能力不足 参考文献 1、 Ude A, Atkeson ...
  • 首先是自定义属性值,有哪些可自定义属性值呢? 的背景颜色:circle_color,进度的颜色:progress_color,进度显示文字的颜色:text_color,进度文字的大小:text_size,还有最后一个:波纹最大高度:ripple_...
  • 从上图,我们基本上就可以看出方向分布工具的主要作用了,它可以识别一组数据的方向以及分布的趋势,并且了解到这份数据是否具有一些特性,至于有哪些特性,我们后面再说。   我们先来看看这个标准差椭圆的...
  • Android 动态设置Shape

    千次阅读 2017-08-24 18:38:19
    引言:之前涉及到设置...于是就想用动态设置shape的方式来替换静态配置shape标签。静态配置shape这个不多说了,梯子备好了,自行前往! https://developer.android.google.cn/guide/topics/resources/drawable-resour
  • DOT:视觉SLAM的动态目标物跟踪

    千次阅读 2020-11-23 07:00:00
    为了确定哪些目标实际在移动,首先是对潜在的移动对象进行对象的实例分割,然后根据估计的相机运动,通过最小化光度重投影误差来跟踪这些对象。与其他方法相比,这种短期跟踪的方法提高了分割的准确性。最终,根据...
  • 梵塔问题求解及动态显示

    千次阅读 2020-05-17 13:07:15
    梵塔问题—三个杆标号分别为A、B、C,初始时在A杆从上到下,按从小到大的顺序放了n个圆盘。需要在有限步数下将n个圆盘平移到C,在平移的过程中,A、B、C杆上的圆盘自上到下都要服从圆盘大小自小到大。 那么怎样求解...
  • 对向来船(动态障碍)和静态障碍 三船情景一 三船情景二 基于人工势场法的避障 请点赞+收藏 可私信
  • 作者:拼搏的80后全文共 2420 字 6 图,阅读需要 5 分钟———— / BEGIN / ————动态面板是Axure中使用频率最高的元件之一,动态面板专门用于设计...
  • Blender:雕刻笔刷动态图解(一)

    千次阅读 多人点赞 2019-08-31 13:35:14
    本文基于Blender 2.8正式版 Draw(自由线,自由绘制)笔刷,快捷键:X或Space , X Draw笔刷有点像往表面挤牙膏。...Clay Strips(黏条,黏土条)笔刷,快捷键:Space , 1 ...Clay Strips笔刷模拟传统雕刻中往表面一层一...
  • 直线与的位置关系怎么判断

    千次阅读 2017-06-21 16:37:00
    《直线与的位置关系》这个知识点应用比较广泛,是几何知识的一个综合运用,在今后的解题及几何证明中,将起到重要的作用,所以就必须熟练掌握它们之间有哪些位置关系。为了更好地理解,我们可以借助数学绘图工具来...
  • 动态规划模板总结

    千次阅读 多人点赞 2018-08-06 17:06:47
    动态规划常常适用于重叠子问题和最优子结构性质的问题,动态规划方法所耗时间往往远少于朴素解法。 试用情况: 最优子结构性质。如果问题的最优解所包含的子问题的解也是最优的,我们就称该问题具有最优子结构...
  • 例如在军事情报分析系统中,将多源异构信息进行整合,如电子表格、电话、文档、传感器数据、动态视频等,可以对人员、装备、事件进行全方位实时的监控分析,使调度人员第一时间掌握战场态势,并做出预判。...
  • MySQL需要掌握的技能有哪些?超细长文带你掌握MySQL

    万次阅读 多人点赞 2021-09-02 21:41:39
    本篇博客几乎涵盖了所有MySQL知识点,文中也特别标注了哪些是面试提问热点或者是应该着重掌握的知识点。你也可以把这篇博客当作一本小“词典”,遇到遗忘了的知识点也随时可以查阅。总而言之,希望大家喜欢这篇...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 34,412
精华内容 13,764
关键字:

动态的圆有哪些