2009-01-16 9 views

Antwort

3

[Meine Antwort ist nicht mehr korrekt, Verläufe in Reportlab jetzt verfügbar sind, auf dieser Seite für Details die andere Antwort sehen.]

Leider diese Frage ressurect, aber ich über ihn gestolpert und es hadn wurde nicht richtig beantwortet.

Die Antwort lautet nein, ab heute unterstützt die aktuelle Version von ReportLab keine Gradienten. Farbverläufe werden jedoch von PDF unterstützt. Wenn Sie in der Canvas-Klasse von ReportLab nachsehen, werden Sie feststellen, dass viele seiner Methoden relativ kleine Wrapper für die zugrunde liegende PDF-Code-Generierung sind. Um auf Farbverläufe in RL zuzugreifen, müssen Sie die Canvas-Klasse erweitern und zusätzliche Methoden hinzufügen, um den richtigen PDF-Code zu generieren. Dies ist machbar, aber offensichtlich nicht trivial, und es bedeutet, dass Sie die PDF-Spezifikation lesen müssen.

Es gibt zwei Alternativen. Erzeugen Sie als erstes den Farbverlauf als Rasterbild und verwenden Sie das, erzeugen Sie zweitens den Farbverlauf, indem Sie eine ganze Reihe von Rechtecken in verschiedenen Farben zeichnen.

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) 

Zum Beispiel. Leider erfordert das Glätten des Verlaufs viele Rechtecke, und dies kann dazu führen, dass das PDF groß und langsam gerendert wird. Sie sind besser mit dem Raster-Ansatz.

Schließlich könnten Sie PyCairo verwenden. Dies bietet eine bessere Unterstützung für viele grafische Elemente und kann als PDF oder PNG gerendert werden. Es fehlen jedoch ReportLabs höhere Hebelkonstrukte (wie Seitenlayout).

6

ReportLab unterstützt jetzt PDF-Verläufe.

Ein Patch für Gradientenunterstützung war posted to the ReportLab mailing list von Peter Johnson am 6. August 2012 und war added to the source am nächsten Tag. Ich kann nichts in the release notes for ReportLab 2.6 finden, aber da das am 1. Oktober 2012 veröffentlicht wurde, ist es vermutlich dort. Es ist definitiv in 2.7 vorhanden.

Sowohl lineare als auch radiale Gradienten mit mehreren Stopps können angegeben werden. Suchen Sie in der Dokumentation für den Begriff Gradient nichts auf. Die hat jedoch ein paar Beispiele, die die Basis von some tests in the ReportLab source sind. Auf dieser Grundlage habe ich eine kurze Demo-Skript aufgearbeitet:

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

Diese gibt sechs Seiten mit verschiedenen Steigungen und dem Gradienten Methodenaufruf und Linien/Kreise zeigt, wo die Endpunkte und Haltestellen sind:

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

Sie wollen ein Rechteck füllen (o r anderer Weg) mit einem Gradienten anstelle von eine einfarbige?

Kein Problem. Verwenden Sie Clipping, um den Farbverlauf an einen Pfad zu binden/zu begrenzen. Denken Sie daran, den Clip-Pfad vor Einstellung des Gradienten zu setzen. (Und wickeln Sie es in saveState()/restoreState(), um den Clip und den Farbverlauf anschließend zurückzusetzen.

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

Für radiale Gradienten könnte es ausreichen, um das Schlüsselwort extend Parameter False einzustellen.

+0

Während es hier nützliche Informationen gibt, sollte es sich um die eigentliche Frage handeln, nicht um eine Frage in einer anderen Antwort. –

+0

@ ZAD-Man Nun, wenn Sie nicht die gesamte Seite mit einem linearen Verlauf füllen wollen, müssen Sie den Beschneidungspfad (AFAIK) verwenden. Ich bin mir ziemlich sicher, dass die meisten Anwendungsfälle das Füllen von Regionen der Seite beinhalten. Ich bin kein Fan von pedantisch interpretieren, was die Leute sagen/schreiben. Normalerweise antworte ich auf das, was ich denke, das Poster versucht zu fragen/zu tun/herauszufinden. Und wenn ich es tue; Ich beginne meine Antwort mit der Aussage, wie ich die Frage interpretiere. –

+0

Nun, was ich meine, ist die Tatsache, dass Ihre Antwort eine jetzt gelöschte "Antwort" beantwortet, die eine neue Frage hätte sein sollen. Ihr Zitat zu Beginn wird von dieser entfernten Antwort genommen. Wie ich schon sagte, gibt es hier gute Informationen, aber es sollte bearbeitet werden, um Verweise auf die andere "Antwort" zu entfernen, um mögliche Verwirrung zu vermeiden, besonders jetzt, nachdem die andere gelöscht wurde. –

Verwandte Themen