Using bezier curves to draw a rectangle with rounded corners in PyMuPDF
Question:
I would like to use PyMuPDF
to draw a rectangle with rounded corners in a pdf. Apparently, there are no particular methods for rounded rectangles. But I was wondering if Shape.draw_bezier()
or Shape.draw_curve()
could be used for that purpose, making a stroke that recovers the shape of the rectangle.
Answers:
Interest question! This is possible with PyMuPDF, but currently still a bit clumsy to do. The basic approach I would suggest is
- Define a normal rectangle within your final one should land.
- At each of the four corner define 2 points ("helper points"), which will become the start and end of method
draw_curve()
(which you correctly identified yourself already – chapeau!).
- Then start drawing. The shape will consist of 4 curves and 4 lines, every line followed by a curve, followed by a line …
Here is the code:
import fitz
doc = fitz.open()
page = doc.new_page()
rect = fitz.Rect(100, 100, 300, 200)
d = 10 # controls how round the edges are
# make a shape to get properly connect points
shape = page.new_shape()
lp = shape.draw_line(rect.bl + (d, 0), rect.br - (d, 0))
lp = shape.draw_curve(lp, rect.br, rect.br - (0, d))
lp = shape.draw_line(lp, rect.tr + (0, d))
lp = shape.draw_curve(lp, rect.tr, rect.tr - (d, 0))
lp = shape.draw_line(lp, rect.tl + (d, 0))
lp = shape.draw_curve(lp, rect.tl, rect.tl + (0, d))
lp = shape.draw_line(lp, rect.bl - (0, d))
lp = shape.draw_curve(lp, rect.bl, rect.bl + (d, 0))
shape.finish(color=(1, 0, 0), fill=(1, 1, 0), closePath=False)
shape.commit()
doc.save(__file__.replace(".py", ".pdf"))
I would like to use PyMuPDF
to draw a rectangle with rounded corners in a pdf. Apparently, there are no particular methods for rounded rectangles. But I was wondering if Shape.draw_bezier()
or Shape.draw_curve()
could be used for that purpose, making a stroke that recovers the shape of the rectangle.
Interest question! This is possible with PyMuPDF, but currently still a bit clumsy to do. The basic approach I would suggest is
- Define a normal rectangle within your final one should land.
- At each of the four corner define 2 points ("helper points"), which will become the start and end of method
draw_curve()
(which you correctly identified yourself already – chapeau!). - Then start drawing. The shape will consist of 4 curves and 4 lines, every line followed by a curve, followed by a line …
Here is the code:
import fitz
doc = fitz.open()
page = doc.new_page()
rect = fitz.Rect(100, 100, 300, 200)
d = 10 # controls how round the edges are
# make a shape to get properly connect points
shape = page.new_shape()
lp = shape.draw_line(rect.bl + (d, 0), rect.br - (d, 0))
lp = shape.draw_curve(lp, rect.br, rect.br - (0, d))
lp = shape.draw_line(lp, rect.tr + (0, d))
lp = shape.draw_curve(lp, rect.tr, rect.tr - (d, 0))
lp = shape.draw_line(lp, rect.tl + (d, 0))
lp = shape.draw_curve(lp, rect.tl, rect.tl + (0, d))
lp = shape.draw_line(lp, rect.bl - (0, d))
lp = shape.draw_curve(lp, rect.bl, rect.bl + (d, 0))
shape.finish(color=(1, 0, 0), fill=(1, 1, 0), closePath=False)
shape.commit()
doc.save(__file__.replace(".py", ".pdf"))