2009-01-16 21 views

Respuesta

3

[Mi respuesta ya no es correcta, gradientes están ahora disponibles en ReportLab, ver la otra respuesta en esta página para obtener más detalles.]

sentimos a resucitar esta pregunta, pero me encontré con él y hadn ha sido respondida correctamente

La respuesta es no, a partir de hoy, la versión actual de ReportLab no admite gradientes. Los degradados son compatibles con PDF, sin embargo. Si observas en la clase Canvas de ReportLab, verás que muchos de sus métodos son envoltorios relativamente pequeños en torno a la generación del código PDF subyacente. Para acceder a los degradados en RL, deberá extender la clase Canvas y agregar métodos adicionales para generar el código PDF correcto. Esto es posible, pero obviamente no es trivial, y significa que tendrías que leer las especificaciones de PDF.

Hay dos alternativas. Primero genere el degradado como una imagen ráster y utilícelo, en segundo lugar, genere el degradado dibujando una serie completa de rectángulos en diferentes colores.

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) 

Por ejemplo. Desafortunadamente, obtener el gradiente sin problemas toma muchos rectángulos, y esto puede hacer que el PDF sea grande y se renderice lentamente. Estás mejor con el enfoque de trama.

Finalmente, puede considerar el uso de PyCairo. Esto tiene mejor soporte para muchos elementos gráficos, y puede renderizarse en PDF o PNG. Sin embargo, carece de construcciones de palanca superior de Reportlabs (como el diseño de página).

6

ReportLab ahora es compatible con degradados de PDF.

Un parche para soporte de gradiente fue posted to the ReportLab mailing list por Peter Johnson el 6 de agosto de 2012 y fue added to the source al día siguiente. No puedo encontrar nada en the release notes for ReportLab 2.6, pero dado que fue lanzado el 1 de octubre de 2012, presumiblemente está allí. Está definitivamente presente en 2.7.

Se pueden especificar tanto gradientes lineales como radiales con paradas múltiples. La búsqueda en la documentación del término gradiente no muestra nada. Sin embargo, el message with the first version of the patch tiene un par de ejemplos que son la base de some tests in the ReportLab source. En base a esta He trabajado hasta un script de demostración rápida:

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() 

Esto da salida a seis páginas con diferentes gradientes más el llamado método del gradiente y líneas/círculos que muestran en los puntos finales y las paradas son:

Basic linear gradient extending over page Linear gradient constrained within endpoints Linear gradient with multiple stops Basic radial gradient extending over page Radial gradient constrained within radius Radial gradient with multiple stops

0

que desea rellenar un rectángulo (o r otra ruta) con un gradiente en lugar de ¿un color sólido?

No hay problema. Use recorte para enlazar/limitar el degradado a una ruta. Simplemente recuerde configurar la ruta del clip antes de configurando el degradado. (Y envuélvalo dentro de saveState()/restoreState() para restablecer el clip y el degradado después.)

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)) 

Para gradientes radiales que podría ser suficiente para establecer el parámetro extend palabra clave para False.

+0

Si bien hay información útil aquí, debe abordar la pregunta real, no una pregunta formulada en otra respuesta. –

+0

@ ZAD-Man Bueno, a menos que desee llenar toda la página con un degradado lineal, debe usar el trazado de recorte (AFAIK). Estoy bastante seguro de que la mayoría de los casos de uso implica llenar regiones de la página. No soy partidario de interpretar pedante lo que dice/escribe la gente. Normalmente respondo a lo que, creo, el póster intenta hacer/hacer/descubrir. Y cuando lo haga; Comienzo mi respuesta diciendo cómo interpreté la pregunta. –

+0

Bueno, a lo que me refiero es al hecho de que su respuesta está respondiendo a una "respuesta" ahora eliminada que debería haber sido una pregunta nueva. Su cita al principio está tomada de esa respuesta eliminada. Como dije, hay buena información aquí, pero debe ser editada para eliminar las referencias a la otra "respuesta", para reducir la posible confusión, especialmente ahora que la otra ha sido eliminada. –

Cuestiones relacionadas