Wie die Stücke von Android (2D) Canvas-Zeichnung, die pipeline passt das zusammen?
Ich würde gerne besser verstehen, wie die Komponenten von Android (2D) Canvas-Zeichnung, die pipeline zusammen passen.
Angenommen, wie XferMode, Shader, MaskFilter und ColorFilter interagieren? Die Referenz-Dokumentation für diese Klassen sind ziemlich spärlich und die docs für Leinwand und Farbe nicht wirklich eine nützliche Erklärung.
Es ist auch mir nicht ganz klar, wie die Zeichenoperationen, die inneren Farben (z.B.: drawBitmap
, im Vergleich zum "Vektor" primitive wie drawRect
) passen in alle diese-nicht immer ignorieren die Paint
's Farbe und Verwendung Ihrer intrinsischen Farbe statt?
Ich war auch überrascht von der Tatsache, dass man etwas wie das hier tun:
Paint eraser = new Paint();
eraser.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
canvas.drawOval(rectF, eraser);
Diese löscht ein oval. Bevor ich dies bemerkte meine geistige-Modell war, dass die Zeichnung auf eine Leinwand (konzeptionell) zieht, um eine separate "Schicht" und dann, die Schicht aus mit der Leinwand-Bitmap mit der Farbe die transfer-Modus. Wenn es so einfach, dann würde der obige code löscht die gesamte Bitmap (innerhalb der clipping region) als KLARE immer wird die Farbe (und alpha) auf 0 unabhängig von der Quelle der alpha. So impliziert dies, dass es eine zusätzliche Art von Maskierung gehen auf die beschränken, die radieren die sich zu einem oval.
Ich fand die API-demos aber jeder demo "im Vakuum" und nicht zeigen, wie die Sache es den Fokus auf (z.B.: XferModes) interagiert mit anderen Sachen (zB: ColorFilters).
Mit genügend Zeit und Mühe konnte ich empirisch herausfinden, wie diese Stücke beziehen, oder gehen Sie entziffern die Quelle, aber ich bin der Hoffnung, dass jemand anderes hat bereits herausgearbeitet, oder noch besser, dass es einige tatsächliche Dokumentation der pipeline/Zeichnung-Modell, das habe ich verpasst.
Diese Frage wurde inspiriert durch den Anblick der code in diese Antwort auf eine andere Frage ALSO.
Update
Während der Suche rund um für eine Dokumentation ist mir eingefallen, dass da viel die Sachen, die ich bin daran interessiert, hier zu sein scheint, eine ziemlich dünne Furnier auf der Oberseite der skia, vielleicht gibt es einen skia-Dokumentation, die nützlich sein würde. Das beste, was ich finden konnte ist die Dokumentation für SkPaint
, die sagt:
Gibt es 6 Arten von Effekten, können
zugeordnet werden Farbe:
- SkPathEffect - änderungen der geometrie (Pfad), bevor es erzeugt eine
alpha-Maske (z.B. schneidigen)- SkRasterizer - verfassen von benutzerdefinierten Masken-Ebenen (z.B. Schatten)
- SkMaskFilter - änderungen an der alpha-Maske, bevor es eingefärbt und
gezeichnet (z.B. Weichzeichner, Relief)- SkShader - z.B. Farbverläufe (linear, radial-sweep), bitmap-Muster
(Klammer -, repeat -, Spiegel)- SkColorFilter - ändern Sie die Quell-color(s) vor der Anwendung der xfermode
(z.B. Farb-matrix)- SkXfermode - z.B. porter-duff transfermodes, blend-Modi
Es nicht ausdrücklich, aber ich vermute, dass die Reihenfolge der Effekte ist hier die Reihenfolge in der pipeline.
- Sie sind am besten zu verstehen, wie mathematische Funktionen nehmen (alpha, color) - Tupel von 1-oder 2-Quelle der Bilder, und zur Ausgabe eines Tupels. hi-android.info/doc/android/graphics/PorterDuff.Mode.html (Buchung Nicht als eine Antwort, denn ich habe noch nie verwendet, Skia; nur auf der Basis der web-Suche Ergebnisse)
- Das ist eine feine Erklärung PorterDuff.Modus, aber es nicht wirklich erklären, die gesamte pipeline. Siehe den Teil meiner Frage zu PorterDuff.- Modus.KLAR und drawOval, zum Beispiel. KLAR definiert ist wie immer die Ausgabe 0 an sowohl alpha-und die Farb-Kanäle unabhängig von den Eingängen, so dass die Anwendung KLAR sollte wischen Sie die gesamte Ziel-es sei denn, es gibt einige weitere Maskierung Einschränkung der Anwendung der mathematischen Funktion
clear(src, dst) = [0,0]
. - warum sind Sie der Annahme, dass es extra Maskierung? Das oval an sich ist die Maske. Der software-renderer nicht stört blending Pixel außerhalb der Form, die Sie versuchen zu ziehen. Deine Erklärung würde nur arbeiten mit einer bitmap.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wie Romain Guy sagte, "Diese Frage ist schwer zu beantworten, auf StackOverflow". Es war nicht wirklich eine vollständige Dokumentation und lückenlose Dokumentation wäre irgendwie groß, um Sie hier zu zitieren.
Landete ich mit dem Lesen der Quell-und dabei eine Reihe von Experimenten. Ich machte mir Notizen auf dem Weg, und am Ende drehen Sie in einem Dokument, das Sie hier sehen können:
sowie dieses Diagramm:
Ist es "inoffizielle", offensichtlich, so dass die normalen Vorsichtsmaßnahmen gelten.
Basierend auf den oben, hier sind die Antworten auf einige der "sub-Fragen":
Die "Quelle der Farben" kommt von der
Shader
. IndrawBitmap
dieShader
wird vorübergehend ersetzt durch einBitmapShader
wenn ein nicht-ALPHA_8
Bitmap
verwendet wird. In anderen Fällen, wenn keineShader
angegeben ist eineShader
dass nur erzeugt eine solide Farbe, diePaint
's Farbe, verwendet wird.Den
XferMode
gilt für die "Quelle der Farben" (von derShader
) und die "Zielfarbe" (aus derCanvas
'sBitmap
). Das Ergebnis wird dann gemischt mit dem Ziel mit der Maske berechnet, die in die Rasterung. Finden Sie in der Transfer-phase in der oben genannten Dokuments für weitere details.Error 403 - Forbidden You tried to access a document for which you don't have privileges.
auf Ihren link(x,y) → (α,r,g,b)
Funktion als Bild (wenn auch "virtuellen"). Ich bin nicht ganz glücklich mit der Art und Weise, dass ein Teil geschrieben, also werde ich wahrscheinlich gehen Sie zurück und schreiben es, und ich werde auf jeden Fall euer feedback zu berücksichtigen.Diese Frage ist schwer zu beantworten, auf StackOverflow. Bevor ich loslege beachten Sie jedoch, dass Formen (drawRect() zum Beispiel) haben keinen wirklichen Farbe. Die Farbe Informationen immer kommt aus dem Paint-Objekt.
Ihrem Modell ein bisschen ab. Das oval ist nicht gezogen in eine eigene Ebene (es sei denn, Sie rufen Leinwand.saveLayer()), es gezeichnet wird direkt auf die Leinwand " backing bitmap. Die Farbe ist transfer-Modus angewendet wird, um jedes pixel gezeichnet wird, indem Sie die primitiven. In diesem Fall wird nur das Ergebnis der Rasterung oval wirkt sich auf die Bitmap. Es gibt keine speziellen Maskierung auf, das oval selbst ist die Maske.
Jedenfalls, hier ist eine vereinfachte Ansicht der pipeline:
(Ich sah gerade deinen update-und ja, was Sie fand, beschreibt Sie die Phasen der pipeline in der Reihenfolge.)
Die pipeline wird nur ein wenig komplizierter als die Verwendung von Ebenen (Canvas.saveLayer()), wie die pipeline verdoppelt. Sie gehen zuerst durch die pipeline zum Rendern der primitive(s) in eine offscreen-bitmap (die Ebene), und die offscreen-bitmap wird dann angewendet, um die Leinwand, indem Sie durch die pipeline.
SkMask
zu vertreten. Ich entdeckte auch, dass dieMaskFilter
nur nimmt das Ergebnis der integrierten Rasterung (dh: scan-Konvertierung derPath
) und scheint nicht zu gelten, um das Ergebnis einerRasterizer
wenn einer vorhanden ist. Dies scheint ein bug... weißt du, ob dieses Verhalten beabsichtigt war?SkPathEffect - änderungen der geometrie (Pfad), bevor es erzeugt eine alpha-Maske (z.B. schneidigen)
SkRasterizer - verfassen von benutzerdefinierten Masken-Ebenen (z.B. Schatten)
SkMaskFilter - änderungen der alpha-Maske, bevor es gefärbt und gezeichnet (z.B. Weichzeichner)
SkShader - z.B. Farbverläufe (linear, radial-sweep), bitmap-Muster (clamp, wiederholen, spiegeln)
SkColorFilter - ändern Sie die Quell-color(s) vor der Anwendung der xfermode (z.B. Farb-matrix)
SkXfermode - z.B. porter-duff transfermodes, blend-Modi
http://imgur.com/0X5Yqod