Можно ли создать градиентную заливку в формате PDF с помощью ReportLab (python)?
Создание градиента в PDF файле с использованием reportlab
Ответ 1
ReportLab теперь поддерживает градиенты PDF.
Патч для поддержки градиента был отправлен в список рассылки ReportLab Питером Джонсоном 6 августа 2012 года и был добавлен в источник на следующий день. Я ничего не могу заметить в примечаниях к выпуску ReportLab 2.6, но так как это было выпущено 1 октября 2012 года, предположительно, оно там. Он определенно присутствует в 2.7.
Можно указать как линейные, так и радиальные градиенты с несколькими остановками. Поиск документации для градиента термина не вызывает ничего. Однако сообщение с первой версией патча содержит несколько примеров, лежащих в основе некоторые тесты в источнике ReportLab. Основываясь на этом, я разработал быстрое демо script:
from reportlab.pdfgen.canvas import Canvas
from reportlab.lib.colors import red, yellow, green
from reportlab.lib.units import mm
c = Canvas("gradient.pdf")
# Linear gradient with the endpoints extending over the page.
c.linearGradient(105*mm, 200*mm, 180*mm, 100*mm, (red, yellow))
c.drawString(5*mm, 290*mm, "c.linearGradient(105*mm, 200*mm, 180*mm, 100*mm, (red, yellow))")
c.line(105*mm, 200*mm, 180*mm, 100*mm)
c.showPage()
# Linear gradient constrained within the endpoints.
c.linearGradient(105*mm, 200*mm, 180*mm, 100*mm, (red, yellow), extend=False)
c.drawString(5*mm, 290*mm, "c.linearGradient(105*mm, 200*mm, 180*mm, 100*mm, (red, yellow), extend=False)")
c.line(105*mm, 200*mm, 180*mm, 100*mm)
c.showPage()
# Linear gradient with multiple stops.
c.linearGradient(105*mm, 200*mm, 180*mm, 100*mm, (red, yellow, green), (0, 0.8, 1), extend=False)
c.drawString(5*mm, 290*mm, "c.linearGradient(105*mm, 200*mm, 180*mm, 100*mm, (red, yellow, green), (0, 0.8, 1), extend=False)")
c.line(105*mm, 200*mm, 180*mm, 100*mm)
c.line(141*mm, 102*mm, 189*mm, 138*mm)
c.showPage()
# Radial gradient with the endpoint extending over the page.
c.radialGradient(105*mm, 200*mm, 60*mm, (red, yellow))
c.drawString(5*mm, 290*mm, "c.radialGradient(105*mm, 200*mm, 60*mm, (red, yellow))")
c.circle(105*mm, 200*mm, 60*mm)
c.showPage()
# Radial gradient constrained within the circle.
c.radialGradient(105*mm, 200*mm, 60*mm, (red, yellow), extend=False)
c.drawString(5*mm, 290*mm, "c.radialGradient(105*mm, 200*mm, 60*mm, (red, yellow), extend=False)")
c.circle(105*mm, 200*mm, 60*mm)
c.showPage()
# Radial gradient with multiple stops.
c.radialGradient(105*mm, 200*mm, 60*mm, (red, yellow, green), (0, 0.8, 1))
c.drawString(5*mm, 290*mm, "c.radialGradient(105*mm, 200*mm, 60*mm, (red, yellow, green), (0, 0.8, 1))")
c.circle(105*mm, 200*mm, 48*mm)
c.circle(105*mm, 200*mm, 60*mm)
c.showPage()
c.save()
Это выводит шесть страниц с различными градиентами плюс вызов метода градиента и строки/круги, показывающие, где конечные точки и остановки:
Ответ 2
[Мой ответ больше не верен, теперь градиенты доступны в Reportlab, см. другой ответ на этой странице для деталей.]
Извините за этот вопрос, но я наткнулся на него, и на него не ответили правильно.
Ответ на этот вопрос отсутствует, на сегодняшний день текущая версия ReportLab не поддерживает градиенты. Однако градиенты поддерживаются PDF. Если вы посмотрите в классе Canvas ReportLab, вы увидите, что многие из его методов - относительно небольшие обертки вокруг генерации базового PDF-кода. Чтобы получить доступ к градиентам в RL, вам необходимо расширить класс Canvas и добавить дополнительные методы для создания правильного PDF-кода. Это выполнимо, но, очевидно, не тривиально, и это означает, что вам нужно будет прочитать спецификацию PDF.
Есть две альтернативы. Сначала создайте градиент как растровое изображение и используйте его, во-вторых, сгенерируйте градиент, рисуя целую серию прямоугольников разных цветов.
start_color = (1,0,0)
end_color = (0,1,0)
for i in range(100):
p = i * 0.01
canvas.setFillColorRGB(*[start_color[i]*(1.0-p)+end_color[i]*p for i in range(3)])
canvas.rect(i, 0, 2, 100)
Например. К сожалению, получение градиента гладкой занимает много прямоугольников, и это может привести к тому, что PDF будет большим и будет отображаться медленно. Вам лучше использовать растровый подход.
Наконец, вы можете использовать PyCairo. Это улучшает поддержку множества графических элементов и может отображать PDF или PNG. Тем не менее, в нем отсутствуют заголовки с более высокими рычагами (например, макет страницы).
Ответ 3
Вы хотите заполнить прямоугольник (или другой путь) градиентом вместо сплошной цвет?
Нет проблем. Используйте обрезку для привязки/ограничения градиента до пути. Не забудьте установить путь клипа перед установкой градиента. (И оберните его внутри saveState()
/restoreState()
до reset клипа и градиента впоследствии.)
c = canvas.Canvas (filename)
#c.translate (8*cm, 8*cm) # use this to move the rectangle
p = c.beginPath()
p.rect (0,0 , 5*cm,5*cm)
c.clipPath (p, stroke=0)
c.linearGradient (0,0 , 5*cm, 5*cm , (red, yellow))
Для радиальных градиентов может быть достаточно установить параметр ключевого слова extend
на False
.