How to fill to partially fill a shape? #6271
-
I am working on a progress bar, and the example I have seen so far takes several steps: Instead, can I draw on ellipse with a background color, and then fill it up partially to indicate progress? The problem with the above example is that it does not represent the 0% - 1% progress very well, making it all look like one big dot. I want the small numbers to be accurately represented. |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 5 replies
-
I still would like to find a better way to do this (partially fill a shape), but here is what I came up with: def drawProgressBar(progress, bg="black", fg="red"):
x=10
y=10
h=25
w=200
s=x # starting x coord
e=w # ending x coord
box_X=w+50
box_Y=h+25
if progress < 0.01:
progress = 0
if progress > 1:
progress = 1
# create the canvas
out = Image.new("RGB", (box_X, box_Y), (66,66,66))
d = ImageDraw.Draw(out)
w *= progress
## if progress < .5 (half)
# put the "progress" in the background with 2 objects (begin ellipse and rectangle)
# put the "unfinished" part in the foreground with 3 objects (begin ellipse, rectangle, end ellipse)
# make the unfinished begin ellipse get flatter and flatter as it approaches 50%
## if progress >= .5 (half)
# put the "progress" in the foreground with 3 objects (begin ellipse, rectangle, end ellipse)
# put the "unfinished" part in the background with 2 objects (rectangle, end ellipse)
# make the progress end ellipse start flat and get rounder as it approaches 100%
if progress < 0.5:
# draw progress bar
d.ellipse((x, y, x+h, y+h),fill=fg)
d.rectangle((x+(h/2), y, x+w+(h/2), y+h),fill=fg)
# d.ellipse((x+w, y, x+h+w, y+h),fill=fg)
# draw background (unfinished portion)
d.ellipse((x+w, y, x+w+(h*(1-(2*progress))), y+h), fill=bg)
d.rectangle((x+w+(h/2)-(h*progress), y, e+(h/2), y+h), fill=bg)
d.ellipse((e, y, e+h, y+h), fill=bg)
if progress >= 0.5:
# draw background (unfinished portion)
# d.ellipse((x, y, x+h, y+h), fill=bg)
d.rectangle((x+w, y, e+(h/2), y+h), fill=bg)
d.ellipse((e, y, e+h, y+h), fill=bg)
# draw progress bar
d.ellipse((x, y, x+h, y+h),fill=fg)
d.rectangle((x+(h/2), y, x+w+(h*(progress-0.5)), y+h),fill=fg)
d.ellipse((x+w, y, x+w+h*2*(progress-0.5), y+h),fill=fg)
# draw the progress bar to given location, width, progress and color
out.save("output.png") |
Beta Was this translation helpful? Give feedback.
-
If you were looking for a way to simplify your code, the If you wanted to just stop drawing a shape at a certain x position, I would talk about masking, but you would like to have the red portion also rounded. I'm not sure what you precisely mean by "accurately represented". Are you after a way to not just fill 0.5% of the width, but instead to also consider every pixel? So that you can fill exactly 0.5% of the ellipse's pixels with red? While also having that red ellipse wax and wane as it moves along? |
Beta Was this translation helpful? Give feedback.
If you were looking for a way to simplify your code, the
rounded_rectangle()
method would be helpful. That would allow you to draw your starting ellipse, middle rectangle and ending ellipse in one line. #4765 (comment) shows an example of a progress bar using that method.If you wanted to just stop drawing a shape at a certain x position, I would talk about masking, but you would like to have the red portion also rounded.
I'm not sure what you precisely mean by "accurately represented". Are you after a way to not just fill 0.5% of the width, but instead to also consider every pixel? So that you can fill exactly 0.5% of the ellipse's pixels with red? While also having that red ellipse wax …