Sie können eine Transformation im Moment kurz bevor der Farbverlauf angewendet wird angeben, wenn Sie den Pinsel nur einmal deklarieren möchten. Beachten Sie, dass die Verwendung von Transformationen viele Konstruktorargumente außer Kraft setzt, die in einer LinearGradientBrush
angegeben werden können.
LinearGradientBrush.Transform Property (System.Drawing.Drawing2D)
Um die Transformation, rufen die Methoden auf dem Bürsten Objekt entsprechend den gewünschten Matrixoperationen zu ändern. Beachten Sie, dass Matrixoperationen nicht kommutativ sind, daher ist die Reihenfolge wichtig. Für Ihre Zwecke werden Sie sie wahrscheinlich in dieser Reihenfolge für jede Wiedergabe Ihrer Rechtecke verwenden wollen: Skalieren, Drehen, Versetzen/Übersetzen.
LinearGradientBrush.ResetTransform Method @ MSDN
LinearGradientBrush.ScaleTransform Method (Single, Single, MatrixOrder) @ MSDN
LinearGradientBrush.RotateTransform Method (Single, MatrixOrder) @ MSDN
LinearGradientBrush.TranslateTransform Method (Single, Single, MatrixOrder) @ MSDN
Beachten Sie, dass die System-Level-Zeichenwerkzeuge nicht tatsächlich eine Rohteildefinition für Farbverlauf enthalten, so dass, wenn Sie Leistungsprobleme haben Beim Erstellen mehrerer Pinsel sollte die Erstellung einer Vielzahl von Farbverlaufsbürsten nicht mehr kosten als der Aufwand von GDI +/System.Drawin g Beibehalten der Daten, die zum Definieren des Farbverlaufs und des Stylings erforderlich sind. Sie können genauso gut einen Pinsel pro Rechteck nach Bedarf erstellen, ohne in die Mathematik einzutauchen, die erforderlich ist, um den Pinsel per Transformation anzupassen.
Brush Functions (Windows) @ MSDN
Hier ist ein Codebeispiel Sie in einer WinForms-Anwendung testen können. Diese App malt Kacheln mit einem Farbverlaufsbürsten mit einem 45-Grad-Gradienten, skaliert auf die größte Dimension der Kachel (naiv berechnet). Wenn Sie sich mit den Werten und Transformationen beschäftigen, stellen Sie möglicherweise fest, dass es sich nicht lohnt, die Technik zu verwenden, die eine Transformation für alle Ihre Rechtecke vornimmt, wenn Sie nicht-triviale Gradienten-Definitionen haben. Andernfalls denken Sie daran, dass Ihre Transformationen auf der Weltebene angewendet werden, und in der GDI-Welt steht die y-Achse auf dem Kopf, während sie in der kartesischen Mathematikwelt von unten nach oben geordnet ist. Dies führt auch dazu, dass der Winkel im Uhrzeigersinn angewendet wird, während in der Trigonometrie der Winkel gegen den Uhrzeigersinn mit zunehmendem Wert für eine nach oben weisende Y-Achse fortschreitet.
using System.Drawing.Drawing2D;
namespace TestMapTransform
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
Rectangle rBrush = new Rectangle(0,0,1,1);
Color startColor = Color.DarkRed;
Color endColor = Color.White;
LinearGradientBrush br = new LinearGradientBrush(rBrush, startColor, endColor, LinearGradientMode.Horizontal);
int wPartitions = 5;
int hPartitions = 5;
int w = this.ClientSize.Width;
w = w - (w % wPartitions) + wPartitions;
int h = this.ClientSize.Height;
h = h - (h % hPartitions) + hPartitions;
for (int hStep = 0; hStep < hPartitions; hStep++)
{
int hUnit = h/hPartitions;
for (int wStep = 0; wStep < wPartitions; wStep++)
{
int wUnit = w/wPartitions;
Rectangle rTile = new Rectangle(wUnit * wStep, hUnit * hStep, wUnit, hUnit);
if (e.ClipRectangle.IntersectsWith(rTile))
{
int maxUnit = wUnit > hUnit ? wUnit : hUnit;
br.ResetTransform();
br.ScaleTransform((float)maxUnit * (float)Math.Sqrt(2d), (float)maxUnit * (float)Math.Sqrt(2d), MatrixOrder.Append);
br.RotateTransform(45f, MatrixOrder.Append);
br.TranslateTransform(wUnit * wStep, hUnit * hStep, MatrixOrder.Append);
e.Graphics.FillRectangle(br, rTile);
br.ResetTransform();
}
}
}
}
private void Form1_Resize(object sender, EventArgs e)
{
this.Invalidate();
}
}
}
Hier ist eine Momentaufnahme der Ausgabe:
Das ist nicht gegen meine Angst einen Farbverlauf zu schaffen für jedes Rechteck hilft. Ich habe tatsächlich 2 Pinsel, die ich für das Malen von 1000 Rechtecken verwenden muss. – Eugen
Sorry Kumpel, aber ich denke du hast keine andere Möglichkeit. Wenn Sie Leistungsprobleme haben, können Sie sie mithilfe von Threads verbessern. Sie können damit Zeit sparen. Wie lange braucht es, um alle diese Rechtecke jetzt zu füllen, indem ein LinearGradientBrush pro Rechteck erstellt wird? – Andres
Ich habe noch nicht getestet, ich hatte nur gehofft, den selben Brush-Erstellungsprozess wie in WPF zu haben und hatte eine Idee, dass mir etwas fehlt. Aber es sieht so aus, als ob das der einzige Weg ist. – Eugen