xda showthread que español developers descargar android skia android-canvas

showthread - ¿Cómo encajan las piezas de la tubería de dibujo de Canvas de Android(2D)?



xda android (3)

Me gustaría tener una mejor comprensión de cómo encajan los componentes de la línea de diseño de lienzo de Android (2D).

Por ejemplo, ¿cómo XferMode , Shader , MaskFilter y ColorFilter ? Los documentos de referencia para estas clases son bastante escasos y los documentos para Canvas y Paint realmente no agregan ninguna explicación útil.

Tampoco me queda del todo claro cómo las operaciones de dibujo que tienen colores intrínsecos (por ejemplo: drawBitmap , frente a las primitivas "vector" como drawRect ) encajan en todo esto - ¿siempre ignoran el color de Paint y utilizan su color intrínseco? ¿en lugar?

También me sorprendió el hecho de que uno puede hacer algo como esto:

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

Esto borra un óvalo. Antes de darme cuenta de esto, mi modelo mental era que dibujar en un lienzo (conceptualmente) se dibuja en una "capa" separada y luego esa capa se compone con el mapa de bits del lienzo usando el modo de transferencia de Paint. Si fuera así de simple, entonces el código anterior borrará todo el mapa de bits (dentro de la región de recorte) ya que CLEAR siempre establece el color (y alfa) en 0 independientemente del alfa de la fuente. Entonces, esto implica que hay un tipo adicional de enmascaramiento para restringir el borrado a un óvalo.

Encontré las demostraciones de la API, pero cada demostración funciona "en el vacío" y no muestra cómo la cosa en la que se enfoca (por ejemplo, XferModes) interactúa con otras cosas (por ej .: ColorFilters).

Con suficiente tiempo y esfuerzo podría descubrir empíricamente cómo se relacionan estas piezas o descifrar la fuente, pero espero que alguien más ya haya resuelto esto, o mejor aún que haya alguna documentación real de la tubería / modelo de dibujo que Me perdí.

Esta pregunta se inspiró al ver el código en esta respuesta a otra pregunta SO .

Actualizar

Mientras buscaba documentación, se me ocurrió que, dado que muchas de las cosas que me interesan aquí parecen ser un poco delgadas, además de la skia , tal vez haya alguna documentación de skia que sea útil. Lo mejor que pude encontrar es la documentación para SkPaint que dice:

Hay 6 tipos de efectos que se pueden asignar a una pintura:

  • SkPathEffect - modificaciones en la geometría (camino) antes de que genere una máscara alfa (por ejemplo, gallardo)
  • SkRasterizer: composición de capas de máscara personalizadas (por ejemplo, sombras)
  • SkMaskFilter: modificaciones en la máscara alfa antes de que se coloree y dibuje (por ejemplo, desenfoque, relieve)
  • SkShader - p. Ej. Gradientes (lineal, radial, barrido), patrones de mapa de bits (pinza, repetición, espejo)
  • SkColorFilter: modifique los colores de origen antes de aplicar el modo xfer (por ejemplo, matriz de colores)
  • SkXfermode - por ejemplo, modos de transferencia porter-duff, modos de fusión

No está explícitamente establecido, pero supongo que el orden de los efectos aquí es el orden en que aparecen en la tubería.


Al igual que Romain Guy, dijo: "Esta pregunta es difícil de responder en ". No había realmente ninguna documentación completa, y la documentación completa sería algo grande para incluir aquí.

Terminé leyendo la fuente y haciendo un montón de experimentos. Tomé notas en el camino y terminé convirtiéndolas en un documento que puedes ver aquí:

así como este diagrama:

http://xenomachina.com/android-canvas-pipeline.png

Es "no oficial", obviamente, por lo que se aplican las advertencias normales.

En base a lo anterior, aquí hay respuestas a algunas de las "subpreguntas":

Tampoco me queda del todo claro cómo las operaciones de dibujo que tienen colores intrínsecos (por ejemplo: drawBitmap , frente a las primitivas "vector" como drawRect ) encajan en todo esto - ¿siempre ignoran el color de Paint y utilizan su color intrínseco? ¿en lugar?

Los "colores fuente" provienen del Shader . En drawBitmap el Shader se reemplaza temporalmente por un BitmapShader si se BitmapShader un ALPHA_8 Bitmap no ALPHA_8 . En otros casos, si no se especifica ningún Shader , se utiliza un Shader que solo genera un color sólido, el color de Paint .

También me sorprendió el hecho de que uno puede hacer algo como esto:

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

Esto borra un óvalo. Antes de darme cuenta de esto, mi modelo mental era que dibujar en un lienzo (conceptualmente) se dibuja en una "capa" separada y luego esa capa se compone con el mapa de bits del lienzo usando el modo de transferencia de Paint. Si fuera así de simple, entonces el código anterior borrará todo el mapa de bits (dentro de la región de recorte) ya que CLEAR siempre establece el color (y alfa) en 0 independientemente del alfa de la fuente. Entonces, esto implica que hay un tipo adicional de enmascaramiento para restringir el borrado a un óvalo.

El XferMode aplica a los "colores de origen" (del Shader ) y los "colores de destino" (del Bitmap del Canvas ). El resultado luego se combina con el destino usando la máscara calculada en Rasterización. Ver la fase de Transferencia en el documento anterior para más detalles.


Esta pregunta es difícil de responder en . Sin embargo, antes de comenzar, tenga en cuenta que las formas (drawRect () por ejemplo) NO tienen un color intrínseco. La información de color siempre proviene del objeto Paint.

Esto borra un óvalo. Antes de darme cuenta de esto, mi modelo mental era que dibujar en un lienzo (conceptualmente) se dibuja en una "capa" separada y luego esa capa se compone con el mapa de bits del lienzo usando el modo de transferencia de Paint. Si fuera así de simple, entonces el código anterior borrará todo el mapa de bits (dentro de la región de recorte) ya que CLEAR siempre establece el color (y alfa) en 0 independientemente del alfa de la fuente. Entonces, esto implica que hay un tipo adicional de enmascaramiento para restringir el borrado a un óvalo.

Tu modelo está un poco apagado. El óvalo no se dibuja en una capa separada (a menos que llame a Canvas.saveLayer ()), se dibuja directamente en el mapa de bits de respaldo de Canvas. El modo de transferencia de Paint se aplica a cada píxel dibujado por la primitiva. En este caso, solo el resultado de la rasterización de un óvalo afecta el mapa de bits. No hay enmascaramiento especial, el óvalo en sí es la máscara.

De todos modos, aquí hay una vista simplificada de la tubería:

  1. Primitivo (rect, oval, camino, etc.)
  2. PathEffect
  3. Rasterización
  4. MaskFilter
  5. Color / Shader / ColorFilter
  6. Xfermode

(Acabo de ver su actualización y sí, lo que encontró describe las etapas de la tubería en orden).

La tubería se vuelve un poco más complicada cuando se usan capas (Canvas.saveLayer ()), ya que la tubería se duplica. Primero ve a través de la tubería para renderizar tu (s) primitivo (s) dentro de un mapa de bits fuera de pantalla (la capa), y el mapa de bits fuera de pantalla se aplica al lienzo yendo a través de la tubería.


SkPathEffect - modificaciones a la geometría (camino) antes de que genere una máscara alfa (por ejemplo, gallardo) SkRasterizer - composición de capas de máscara personalizadas (por ejemplo, sombras) SkMaskFilter - modificaciones a la máscara alfa antes de que se coloree y dibuje (por ejemplo, desenfoque) SkShader - por ejemplo gradientes (lineal, radial, barrido), patrones de mapa de bits (pinza, repetición, espejo) SkColorFilter - modifique los colores de origen antes de aplicar el modo xfer (por ejemplo, matriz de color) SkXfermode - por ejemplo, modos de transferencia porter-duff, modos de fusión

http://imgur.com/0X5Yqod