草庐IT

Python Imaging Library (PIL) 绘图--带渐变的圆角矩形

coder 2023-08-22 原文

我正在尝试使用 PIL 绘制一个带有圆角和颜色渐变填充的矩形。我找到了一个很酷的网站 ( http://web.archive.org/web/20130306020911/http://nadiana.com/pil-tutorial-basic-advanced-drawing#Drawing_Rounded_Corners_Rectangle ),它展示了如何绘制纯色圆角矩形,对此我很满意,但我希望能够绘制一个从顶部开始为浅红色并变为深红色的圆角矩形在底部。

我最初的想法是使用上面网站中的代码绘制一个圆角矩形,然后使用 alpha 混合在圆角矩形上叠加第二个白色到黑色的矩形。我尝试过的一切最终都会在我面前爆炸。

我已经看到一些使用 numpy 的未遂解决方案,但我的技能不足以将这些代码片段转换为成功的解决方案。如果有人可以展示如何修改上面链接中的代码、实现我的叠加想法,或者展示一个完全更好的解决方案以在 Python 中获得带有渐变填充的圆角矩形,我将不胜感激。

干杯, 摩天轮

最佳答案

这是一种非常暴力的方法,但它可以完成工作。生成梯度的代码是从 here 借来的.

from PIL import Image, ImageDraw

def channel(i, c, size, startFill, stopFill):
    """calculate the value of a single color channel for a single pixel"""
    return startFill[c] + int((i * 1.0 / size) * (stopFill[c] - startFill[c]))

def color(i, size, startFill, stopFill):
    """calculate the RGB value of a single pixel"""
    return tuple([channel(i, c, size, startFill, stopFill) for c in range(3)])

def round_corner(radius):
    """Draw a round corner"""
    corner = Image.new('RGBA', (radius, radius), (0, 0, 0, 0))
    draw = ImageDraw.Draw(corner)
    draw.pieslice((0, 0, radius * 2, radius * 2), 180, 270, fill="blue")
    return corner

def apply_grad_to_corner(corner, gradient, backwards = False, topBottom = False):
    width, height = corner.size
    widthIter = range(width)

    if backwards:
        widthIter.reverse()

    for i in xrange(height):
        gradPos = 0
    for j in widthIter:
                if topBottom:
                    pos = (i,j)
                else:
                    pos = (j,i)
        pix = corner.getpixel(pos)
            gradPos+=1
        if pix[3] != 0:
            corner.putpixel(pos,gradient[gradPos])

    return corner

def round_rectangle(size, radius, startFill, stopFill, runTopBottom = False):
    """Draw a rounded rectangle"""
    width, height = size
    rectangle = Image.new('RGBA', size)

    if runTopBottom:
      si = height
    else:
      si = width

    gradient = [ color(i, width, startFill, stopFill) for i in xrange(si) ]

    if runTopBottom:
        modGrad = []
        for i in xrange(height):
           modGrad += [gradient[i]] * width
        rectangle.putdata(modGrad)
    else:
        rectangle.putdata(gradient*height)

    origCorner = round_corner(radius)

    # upper left
    corner = origCorner
    apply_grad_to_corner(corner,gradient,False,runTopBottom)
    rectangle.paste(corner, (0, 0))

    # lower left
    if runTopBottom: 
        gradient.reverse()
        backwards = True
    else:
        backwards = False


    corner = origCorner.rotate(90)
    apply_grad_to_corner(corner,gradient,backwards,runTopBottom)
    rectangle.paste(corner, (0, height - radius))

    # lower right
    if not runTopBottom: 
        gradient.reverse()

    corner = origCorner.rotate(180)
    apply_grad_to_corner(corner,gradient,True,runTopBottom)
    rectangle.paste(corner, (width - radius, height - radius))

    # upper right
    if runTopBottom: 
        gradient.reverse()
        backwards = False
    else:
        backwards = True

    corner = origCorner.rotate(270)
    apply_grad_to_corner(corner,gradient,backwards,runTopBottom)
    rectangle.paste(corner, (width - radius, 0))

    return rectangle

img = round_rectangle((200, 200), 70, (255,0,0), (0,255,0), True)
img.save("test.png", 'PNG')

从左到右运行(runTopBottom = False):

从上到下运行(runTopBottom = True):

关于Python Imaging Library (PIL) 绘图--带渐变的圆角矩形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7787375/

有关Python Imaging Library (PIL) 绘图--带渐变的圆角矩形的更多相关文章

  1. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  2. ruby-on-rails - 回形针调整大小并裁剪为矩形 - 2

    所以我期待一系列不同尺寸和纵横比的照片。我希望能够缩小/拉伸(stretch)照片以尽可能适合200x100矩形,然后裁剪不适合的其余部分。我希望裁剪也发生在中心周围。这可能吗?我对imagemagick文档感到很困惑。谢谢! 最佳答案 Paperclip的#选项将完全满足您的需求:在指定尺寸内最大程度地适应图像,然后在中心处利用重力裁剪多余部分。例子:has_attached_file:photo,:styles=>{:original=>"200x100#"}注意:如果您想保持原样不变并生成额外的裁剪缩略图,只需将:origin

  3. ruby - 在 Ruby 中绘制点和矩形 - 2

    我正在寻找一种简单的方法来绘制大约10个点和矩形,以便能够查看我的算法哪里出了问题。我查看了gnuplot,但似乎绘制矩形特别糟糕。 最佳答案 SVG(MDNTutorial)是一种非常简单的基于文本(XML)的格式,您可以使用Ruby轻松生成它,而无需任何SVG库,并可以在任何现代Web浏览器中查看。这是一个示例:通过字符串插值的SVG点points=(0..5).map{[rand(100)-50,rand(100)-50]}puts#{points.map{|x,y|""}.join("\n")}ENDSVG输出:http:/

  4. ruby - Ruby 有哪些绘图包/API? - 2

    类似:Whatgraphingpackages/APIsexistforPerl?我正在对不同语言的在线图形包进行一些研究,想知道当前有哪些适用于Ruby的最新图形包值得研究。所需的最低功能应包括Google通过itsAPI提供的功能.如能简要介绍所推荐的包/API的主要优势,我们将不胜感激。 最佳答案 我已将以下内容添加为书签,以便在时间允许时进行调查:基于Flash我还没有尝试过这些,但如果你想要活泼的动画,它们看起来都很有前途:amChartsFusionChartsOpenFlashChartZiyagemGoogleCha

  5. 基于C++实现一个支持简单交互绘图小程序 - 2

    资源下载地址:https://download.csdn.net/download/sheziqiong/86763967资源下载地址:https://download.csdn.net/download/sheziqiong/86763967基于C++实现一个支持简单交互绘图小程序一、概要设计1.1开发环境IDE:VisualStudio2019Commity运行环境:window10专业版配置要求:内存4g显卡无要求CPU无要求目的调试编译通过图形应用编码、熟悉flk1.2结构化模块设计图UML类图1.3主要模块功能接口描述Graph.cppvoidShape::add(Pointp)//

  6. 基于ChatGPT的智能问答、ai绘图微信小程序思路 - 2

    ChatGPT![在这里插入图片描述](https://img-blog.csdnimg.cn/186d9ecc453b48be9f19c467da7c3f07.jpegChatGPT是openai公司的一个人工智能机器人产品,目前已经升级到4.0版本。其因便捷高效,已经在大学生、IT届、科研界等领域广为流传。但是直接进入其官网使用有时候并不是那么方便,毕竟他不开放给中国用户使用,我们需要一些魔法才能用上。如果做成一个微信小程序随时随地打开就能用的话,会方便很多。正好openai官方也开放了api供开发者使用。我们可以进入openai官网https://platform.openai.com/

  7. javascript - 绘图工具 - Angular2 - 2

    我对Web应用程序比较陌生,因此才刚刚开始使用Angular2(还没有使用过angularJS)和Typescript。我正在尝试使用Zingchart绘制图表。我经历了5分钟的快速入门以及angular2页面中的教程,并对它的工作原理有了一个不错的了解。我按照Zingchart页面上的说明使用这两个工具(https://blog.zingchart.com/2016/03/16/angular-2-example-zingchart/)在网页上创建了一个图表。但是,我似乎遇到了问题。1)我无法从@angular/core导入AfterView。尽管页面上说我必须使用angular2/

  8. javascript - 如何在表示矩形的数组中获取与某个索引成对 Angular 线的元素 - 2

    考虑一个数组,其长度总是两个数字的乘积。对于下面的数组,l是4,w是5。还有一个给定的索引。我想获得两个数组,其中包含位于穿过该特定索引的对Angular线上的元素。[0,1,2,3,45,6,7,8,910,11,12,13,1415,16,17,18,19]index=7=>[3,7,11,15]and[1,7,13,19]index=16=>[4,8,12,16]and[10,16]index=0=>[0,6,12,18]and[0]我试过以下方法:letarr=Array(20).fill().map((x,i)=>i);functiongetDias(arr,l,w,ind)

  9. javascript - SVG 向圆环图添加径向渐变 - 2

    我正在用d3.js绘制图表。是否可以向圆环图添加径向渐变,这张图片怎么样? 最佳答案 假设圆弧部分是已填充的路径元素,您可以使用径向渐变来获得该结果。参见thissimilarquestion,我们可以重用这个例子来达到:vardataset={apples:[53245,28479,19697,24037,40245],};varwidth=460,height=300,radius=Math.min(width,height)/2;varcolor=d3.scale.category20();varpie=d3.layout.p

  10. javascript - 是否可以使用图像或 CSS 渐变来填充 Google map 中的水域? - 2

    我目前正在从事某个元素,需要将下一个设计实现到Googlemap。我没有在谷歌地图样式引用中找到任何线索来回答这个问题-https://developers.google.com/maps/documentation/javascript/style-reference所以,我想知道-是否有可能(仅使用API)?或者需要一些技巧?例如,我考虑过让水域透明并将虚线图像放在map后面。提前致谢! 最佳答案 在这个回答中,我将讨论关闭map上水几何体的可见性并设置map背后的背景颜色。首先,如前一个答案所述,您必须关闭map的可见性。您可

随机推荐