61 votes

Comment les morceaux de Android (2D) en Toile de dessin pipeline?

Je voudrais avoir une meilleure compréhension de la façon dont les composants de Android (2D) en Toile de dessin pipeline de l'ajustement ensemble.

Comment, par exemple, XferMode, Shader, MaskFilter et ColorFilter interagir? La référence docs pour ces classes sont assez rares et les docs pour la Toile et de la Peinture n'a pas vraiment d'ajouter toute explication utile.

Il n'est également pas tout à fait clair pour moi comment les opérations de dessin qui ont des couleurs intrinsèques (par exemple: drawBitmap, par rapport à la "vecteur" primitives comme drawRect) dans tout cela -- ont-ils toujours ignorer l' Paint's de couleur et utiliser leur couleur intrinsèque à la place?

J'ai également été surpris par le fait que l'on peut faire quelque chose comme ceci:

Paint eraser = new Paint();
eraser.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
canvas.drawOval(rectF, eraser);

Cela efface la forme d'un ovale. Avant que j'ai remarqué c'est mon mental-modèle est que le dessin d'une toile (conceptuellement) aspire à une autre "couche" et puis, cette couche est composée de la Toile Bitmap à l'aide de la Peinture du mode de transfert. Si c'était aussi simple que ça, alors le code ci-dessus serait effacer l'image entière (dans le région de coupure) CLAIR comme toujours définit la couleur (et alpha) à 0 quelle que soit la source de l'alpha. Donc, cela implique qu'il ya un supplément de tri de masquage de passe pour limiter l'effacement d'un ovale.

Je n'ai trouver l' API démos mais chaque démonstration fonctionne "dans le vide" et ne montre pas comment la chose qu'elle met l'accent sur (par exemple: XferModes) interagit avec d'autres trucs (par exemple: ColorFilters).

Avec suffisamment de temps et d'efforts j'ai pu empiriquement à comprendre comment ces pièces se rapportent ou aller déchiffrer la source, mais je suis en espérant que quelqu'un d'autre a déjà travaillé, ou mieux encore qu'il y a une réelle documentation de la canalisation et le dessin-modèle que j'ai manqué.

Cette question a été inspiré par voir le code dans cette réponse à l'autre question.

Mise à jour

Tout en regardant autour pour certains documents, il m'est apparu que depuis beaucoup de choses que je suis intéressé par ici semble être un peu de vernis sur le dessus de skia, peut-être, il y a quelques skia de la documentation qui pourrait être utile. La meilleure chose que j'ai pu trouver est la documentation pour SkPaint qui dit:

Il existe 6 types d'effets qui peuvent être attribué à une peinture:

  • SkPathEffect - des modifications de la géométrie (chemin) avant qu'il ne génère un masque alpha (par exemple, fringant)
  • SkRasterizer - composant personnalisé calques de masque (comme par exemple des ombres)
  • SkMaskFilter - modifications pour le masque alpha avant il est colorisée et (par exemple flou, relief)
  • SkShader - par exemple, des gradients (linéaire, radial, balayage), modèles bitmap (pince, répéter, miroir)
  • SkColorFilter - modifier la couleur source(s) avant l'application de l'xfermode (ex: la couleur de la matrice)
  • SkXfermode - par exemple, porter-duff transfermodes, les modes de fusion

Il n'est pas dit explicitement, mais je devine que l'ordre des effets voici l'ordre qu'ils apparaissent dans le pipeline.

49voto

Laurence Gonsalves Points 50783

Comme Romain Gars a dit, "Cette question est difficile à répondre sur StackOverflow". Il n'y avait pas vraiment de documentation complète, et une documentation complète serait une sorte de gros de l'inclure ici.

J'ai fini la lecture par le biais de la source et de faire un tas d'expériences. J'ai pris des notes sur le chemin, et a fini par se transformer en un document que vous pouvez voir ici:

ainsi que ce schéma:

C'est "non officiel", évidemment, de sorte que la normale mises en garde s'appliquent.

Basé sur la ci-dessus, voici les réponses à certaines des "sous-questions":

Il n'est également pas tout à fait clair pour moi comment les opérations de dessin qui ont intrinsèque les couleurs (par exemple: drawBitmap, par rapport à la le "vecteur" primitives comme drawRect) dans tout cela -- ont-ils toujours ignorer l' Paint's de couleurs et utiliser des leur couleur intrinsèque à la place?

"Les couleurs de la source" viennent de l' Shader. En drawBitmap le Shader est temporairement remplacé par un BitmapShader si un non-ALPHA_8 Bitmap est utilisé. Dans d'autres cas, si aucun Shader est spécifiée, une Shader qui génère simplement une couleur unie, l' Paint's de couleur, est utilisé.

J'ai également été surpris par le fait que on peut faire quelque chose comme ceci:

Paint eraser = new Paint();
eraser.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
canvas.drawOval(rectF, eraser);

Cela efface la forme d'un ovale. Avant, j'ai remarqué mon mental-modèle est que le dessin pour une toile (conceptuellement) tire à sa séparer le "calque" puis ce calque est composé avec de la Toile Bitmap l'utilisation de la Peinture du mode de transfert. Si c' ont été aussi simple que ça, puis au-dessus de la code d'effacer la totalité de l'image Bitmap (dans le région de coupure) CLAIRE toujours définit la couleur (et alpha) à 0 quelle que soit la source de l'alpha. Donc cela implique qu'il y a un tri supplémentaire de masquage de passer à contraindre l'effacement d'un ovale.

L' XferMode s'applique à la "les couleurs de la source" (à partir de l' Shader) et de la destination "couleurs" (à partir de l' Canvass' Bitmap). Le résultat est ensuite mélangé avec de la destination à l'aide du masque calculée dans la Pixellisation. Voir la phase de Transfert dans le document ci-dessus pour plus de détails.

12voto

Romain Guy Points 57114

Cette question est difficile à répondre sur StackOverflow. Avant que je ne commence toutefois, notez que les formes (drawRect() par exemple) n'ont PAS une couleur intrinsèque. Les informations de couleur toujours vient de la Peinture de l'objet.

Cela efface la forme d'un ovale. Avant, j'ai remarqué mon mental-modèle est que le dessin pour une toile (conceptuellement) tire à sa séparer le "calque" puis ce calque est composé avec de la Toile Bitmap l'utilisation de la Peinture du mode de transfert. Si c' ont été aussi simple que ça, puis au-dessus de la code d'effacer la totalité de l'image Bitmap (dans le région de coupure) CLAIRE toujours définit la couleur (et alpha) à 0 quelle que soit la source de l'alpha. Donc cela implique qu'il y a un tri supplémentaire de masquage de passer à contraindre l'effacement d'un ovale.

Votre modèle est un peu hors. L'ovale n'est pas établi dans un calque séparé (sauf si vous appelez de la Toile.saveLayer()), il est dessiné directement sur la Toile " la sauvegarde de l'image. La Peinture est le mode de transfert est appliquée à chaque pixel attiré par la primitive. Dans ce cas, seul le résultat de la pixellisation d'un ovale affecte l'image Bitmap. Il n'y a pas de masquage spécial en cours, l'anneau lui-même est le masque.

De toute façon, ici, c'est une vue simplifiée de la canalisation:

  1. Primitive (rectangle, ovale, chemin, etc...)
  2. PathEffect
  3. Le tramage
  4. MaskFilter
  5. Couleur/Shader/ColorFilter
  6. Xfermode

(Je viens de voir votre mise à jour et oui, ce que vous avez trouvé décrit les étapes du pipeline dans l'ordre.)

Le pipeline devient juste un peu plus compliqué lors de l'utilisation de couches (Toile.saveLayer()), comme le pipeline double. Vous allez d'abord à travers le pipeline de rendu de votre primitif(s) à l'intérieur d'un écran bitmap (la couche), et les limites de l'écran bitmap est ensuite appliquée à la Toile en passant par la canalisation.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X