2

I'm trying to use PIL for a task but the result is very dirty.

What I'm doing is trying to fill a part of a piece of a circle, as you can see on the image.

Here is my code:

def gen_image(values):

    side = 568
    margin = 47
    image = Image.open(settings.MEDIA_ROOT + "/i/promo_circle.jpg")

    draw = ImageDraw.Draw(image)
    draw.ellipse((margin, margin, side-margin, side-margin), outline="white")

    center = side/2
    r = side/2 - margin

    cnt = len(values)

    for n in xrange(cnt):
        angle = n*(360.0/cnt) - 90
        next_angle = (n+1)*(360.0/cnt) - 90
        nr = (r * values[n] / 5)

        max_r = r
        min_r = nr

        for cr in xrange(min_r*10, max_r*10):
            cr = cr/10.0
            draw.arc((side/2-cr, side/2-cr, side/2+cr, side/2+cr), angle, next_angle, fill="white")

    return image
Josh Lee
  • 171,072
  • 38
  • 269
  • 275
Valentin Golev
  • 9,965
  • 10
  • 60
  • 84

3 Answers3

1

It's been a while since I used PIL, but in various other graphics libraries, there's often an aliasing problem when drawing arcs.

Have you tried enabling anti-aliasing or drawing with thicker lines?

[Edit] Having a quick look over the PIL library, I think you're right about line width etc.

Sounds like the easiest thing to do here is to build up a polygon which covers each area. So a pair of points at each end and then a load round the middle to stop the edges looking jagged. Does that make sense?

Jon Cage
  • 36,366
  • 38
  • 137
  • 215
  • no.. and I have no idea how to do this. sorry, I have a very little understanding about images, anti-alasing, etc. I found anti-aliasing in PIL docs here http://www.pythonware.com/library/pil/handbook/image.htm but in some resizing functions, which aren't useful for me. And I have no idea where to set line width. :( – Valentin Golev Jun 02 '10 at 22:46
  • hm, there is something like line width in aggdraw module, http://effbot.org/zone/pythondoc-aggdraw.htm . but I'd really like to use only PIL since I can't simply install whatever libs I want on the server. and aggdraw module is based on PIL, so I don't think it will produce much clearer results (maybe I'm wrong) – Valentin Golev Jun 02 '10 at 22:49
  • hm, yes, makes sense! thank you, I'll try it right now. gonna recall all trigonometry – Valentin Golev Jun 02 '10 at 22:58
1

Instead of erasing with white, consider drawing a mask of just the areas you want to show. Here's an example of this for a circular mask.

How do I generate circular thumbnails with PIL?

Community
  • 1
  • 1
tcarobruce
  • 3,773
  • 21
  • 33
0

You draw a circle on a separate image and then remove the slice of the circle you don't want by creating a triangle over that area and removing it from the image (make it transparent). Then you copy this circle segment into the image where you want it.

If you want a partial ring, draw a circle and then draw a smaller circle to cut from the first, then use radial lines to make a triangle to remove the parts you don't need in the same way.

peawormsworth
  • 1,120
  • 9
  • 9