Подтвердить что ты не робот

Создание градиента в PDF файле с использованием reportlab

Можно ли создать градиентную заливку в формате PDF с помощью ReportLab (python)?

4b9b3361

Ответ 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()

Это выводит шесть страниц с различными градиентами плюс вызов метода градиента и строки/круги, показывающие, где конечные точки и остановки:

Basic linear gradient extending over pageLinear gradient constrained within endpointsLinear gradient with multiple stopsBasic radial gradient extending over pageRadial gradient constrained within radiusRadial gradient with multiple stops

Ответ 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.