python绘制圆角正方形,Python Imaging Library(PIL)图-带有渐变的圆角矩形

I am trying to use PIL to draw a rectangle with rounded corners and a gradient fill for the color. I found a cool web site ( http://web.archive.org/web/20130306020911/http://nadiana.com/pil-tutorial-basic-advanced-drawing#Drawing_Rounded_Corners_Rectangle ) that shows how to draw a solid-color rounded rectangle and I am happy with this, but I want to be able to draw one that starts light red at the top and goes to dark red at the bottom.

My initial thought was to use the code in the website above to draw a rounded rectangle, and then overlay a second white to black rectangle over the rounded rectangle, using alpha blending. Everything that I've tried ends up blowing up in my face.

I have seen some near-miss solutions using numpy, but I am not skilled enough to commute those code fragments to a successful solution. I would be grateful if someone could show how to modify the code in the link above, implement my overlay idea, or show a completely better solution for getting a rounded rectangle with gradient fill in Python.

Cheers,

Ferris

解决方案

This is a very brute force method, but it gets the job done. Code to produce the gradients was borrowed from 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')

Running from left to right (runTopBottom = False):

AGHZy.png

Running from top to bottom (runTopBottom = True):

flpov.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值