Soporte

soporte@chileguia.cl
Categorias

ANDROID CANVAS DRAWING: CLASES Y OPERACIONES GRÁFICAS ÚTILES

Dibujar en un lienzo de Android es bastante abrumador, hay muchas clases y conceptos diferentes para entender al dibujar algo. En esta publicación, cubriremos algunas clases que encontrará disponibles en el Marco de Android que pueden facilitarle la vida al trabajar con un lienzo.

Rect / RectF 

Una clase rectángulo que almacena cuatro valores: top, left, right y bottom. Estos se pueden usar para dibujar directamente en el lienzo o simplemente para almacenar tamaños de objetos que desea dibujar.

La diferencia entre la clase Rect y RectFes que las RectF tiendas almacenan valores flotantes, mientras que la Rect clase almacena enteros.

 

val rect = RectF (100.0f, 200.0f, 300.0f, 400.0f)

 

Con  KTX  hay muchas funciones de extensión de gráficos que debe aprovechar. Por ejemplo, hay algunos para  Rect y  RectF. Una de esas extensiones es la declaración de desestructuración que saca componentes de un  Rect objeto:

 

val rect = RectF (100.0f, 200.0f, 300.0f, 400.0f) 
val (izquierda, arriba, derecha, abajo) = rect
// izquierda = 100.0f, arriba = 200.0f, derecha = 300.0f, abajo = 400.0f

Puede realizar otras operaciones con una  Rect clase, por ejemplo, puede Rects unir dos  . Básicamente, esto solo incluye los puntos de ambos  Rectsy devuelve uno más grande  Rect que contiene ambos  Rects dentro de él. También hay funciones de extensión para esta operación, pero también es posible sin la extensión:

 

val rect = RectF (100.0f, 200.0f, 300.0f, 400.0f)
val otherRect = RectF (50.0f, 400.0f, 150.0f, 500.0f)
rect.union (otherRect)
// rect = RectF (50.0, 200.0, 300.0, 500.0)
// alternativamente:
val combinadoRect = rect + otroRect
// o alternativamente:
val combinadoRect = rect u otroRect
// combinadoRect = RectF (50.0, 200.0, 300.0, 500.0)

Hay otras operaciones que puede realizar en una  Rect, como:  and,  xor,  or.

Punto / PuntoF

Almacena una   coordenada x y  yque representa un "punto" en un lienzo. Point almacena valores enteros, mientras que  PointF almacena valores de coma flotante.

 

punto val = PointF (200.0f, 300.0f)

Si está utilizando KTX, hay algunas funciones de extensión integradas en las   clases Point y  PointFque hacen que trabajar con puntos sea mucho más fácil. Por ejemplo, sobrecargas del operador que agregan la habilidad  plus y  minus dos puntos entre sí.

val start = PointF (100.0f, 30.0f) 
val end = PointF (20.0f, 10.0f)
diferencia de val = start - end
val together = inicio + fin
// together = Point (120.0f, 40.0f)

También existen declaraciones de desestructuración para estas clases, por lo que podemos salir  x y  y coordinarnos fácilmente desde la  Point clase:

val start = PointF (100.0f, 30.0f) 
val end = PointF (20.0f, 10.0f)
val (x, y) = start - end
// x = 80.0fy = 20.0f

Matriz 

Una matriz de 3 por 3 que almacena información que se puede utilizar para transformar un lienzo. A Matrix puede almacenar el siguiente tipo de información de transformación: escala, sesgo, rotación, traslación.

A continuación se muestra un ejemplo del uso de a Matrix para transformar un mapa de bits que se dibuja en un lienzo.

Para usar una matriz al dibujar, puede hacer lo siguiente:

val customMatrix = Matriz ()
// en onDraw ()
customMatrix.postRotate (20.0f)
canvas.withMatrix (customMatrix) {
    drawBitmap (mapa de bits, nulo, rect, pintura)
}

El código anterior dibujará un mapa de bits en un lienzo que se gira a 20 grados. Hay algunas otras funciones en una Matrix que podemos usar, como escalar, rotar y sesgar. La gran parte de usar un Matrix over haciendo todo usted mismo manualmente con las transformaciones de Canvas, es que Matrix contiene información acumulativa sobre las transformaciones que se le aplican.

Si traduce Matrix, rota, escala y traduce nuevamente, los valores finales de la traducción serían un poco diferentes a los valores originales. Si hiciera esto usted mismo, necesitaría calcularlo manualmente si estuviera realizando funciones normales de traducción y escala de Canvas.

preRotate vs proRotate vs setRotate

Tal vez se pregunte qué postRotate significa, considerando el hecho de que existen otros métodos como setRotate y preRotate en a Matrix. Estos tres métodos hacen cosas ligeramente diferentes:

setRotate - Restablece completamente la corriente Matrix y aplica la rotación, perdiendo así cualquier información que ya haya almacenado en su Matrix.

preRotate - La rotación se aplicará antes de lo que Matrix contenga la corriente.

postRotate - La rotación se aplicará después de lo que Matrix contenga la corriente.

Dibujo en perspectiva con matriz

Un Matrix objeto también puede proporcionarnos la capacidad de realizar dibujos en perspectiva, lo que no es posible lograr con solo API de transformación de Canvas estándar. La función que permite dibujar en perspectiva o sesgar un lienzo es Matrix#setPolyToPoly() . Este método suena un poco confuso al principio, pero una vez que comprende cómo funciona, ¡no es tan malo!

Aquí hay un mapa de bits de ejemplo que ha sido "sesgado" usando el setPolyToPolymétodo.

El setPolyToPoly método toma src"puntos" de entrada ( ) y los asigna a los dst"puntos" de salida ( ) especificados . Digo "puntos" porque no son objetos de puntos reales como acabamos de explorar anteriormente en esta publicación, sino que son más bien valores en una matriz flotante, lo que puede ser bastante confuso.

Puede ver en la src matriz a continuación, los dos primeros valores representan el punto superior izquierdo de la imagen, los dos segundos valores representan el punto superior derecho y así sucesivamente. Estos puntos pueden estar en cualquier orden, pero deben coincidir con el punto correspondiente al que desea asignar, en la dstmatriz.

 

val src = floatArrayOf (
    0f, 0f, // punto superior izquierdo
    ancho, 0f, // punto superior derecho
    ancho, alto, // punto inferior derecho
    0f, altura // punto inferior izquierdo
)
val dst = floatArrayOf (
    50f, -200f, // punto superior izquierdo
    ancho, -200f, // punto superior derecho
    ancho, alto + 200f, // punto inferior derecho
    0f, altura // punto inferior izquierdo
)
val pointCount = 4 // número de puntos

// los argumentos segundo y cuarto representan el índice en las matrices src y dest desde el cual los puntos deberían comenzar a mapearse
newMatrix.setPolyToPoly (src, 0, dst, 0, pointCount)

canvas.withMatrix (newMatrix) {
   drawBitmap (mapa de bits, nulo, rect, pintura)
}


En este ejemplo, el punto inferior derecho se asignará de un punto [width, height] a otro [width, height +200f].

Entonces, puede ver en el ejemplo anterior que Matrix puede hacer algunas cosas bastante poderosas e interesantes.

Consejo: use la clase Matrix para trabajar entre diferentes sistemas de coordenadas

Si tiene dos sistemas de coordenadas diferentes con los que está tratando en una sola vista, entonces aprovechar una Matrix clase puede ayudarlo a mapear entre los dos.

Por ejemplo, si obtiene un evento táctil de Android que se mide en la altura y el ancho del tamaño de la pantalla, pero le gustaría saber cuál sería ese punto dentro de la imagen que está dibujando en la pantalla, dentro de ese sistema de coordenadas (es decir, el sistema de coordenadas de la imagen), puede usar a Matrix para asignar entre estos dos sistemas.

Para obtener el punto asignado dentro de la imagen dibujada en la pantalla, podemos usar el  Matrix#mapPoints() método:

fun mapPoint (point: PointF): PointF { 
computeMatrix.reset () // aplica las mismas transformaciones en la matriz que se aplican a la imagen
computeMatrix.postTranslate (20f, 20f)
computeMatrix.postRotate (20f, x, y) // cree una matriz flotante con los puntos que queremos asignar
val arrayPoint = floatArrayOf (point.x, point.y) // use la función de puntos de mapa para aplicar las mismas transformaciones que tiene la matriz, en la matriz de entrada de coordenadas
computeMatrix.mapPoints ( arrayPoint) // saca los puntos de la matriz, estos ahora serán transformados por la matriz.
devolver PointF (arrayPoint [0], arrayPoint [1])
}

En el ejemplo anterior, el punto de entrada sería el evento táctil de Android, y la traducción y rotación que aplicamos  computeMatrix es la misma traducción y rotación que aplicamos en la imagen cuando se dibujó. Luego creamos una matriz flotante que contiene el original  x y el  y punto. Luego llamamos al  mapPoints método con esta matriz. Luego transformará los valores en su lugar y cuando consultamos la matriz para el primer y segundo valor, será la coordenada asignada, que es el punto dentro de la vista de imagen.

Resumen

Puede ver que las API de gráficos de Android contienen muchas clases útiles que puede aprovechar para hacer muchos cálculos y matemáticas por usted. A partir  Points de  Rects las clases de cálculo más complejos, como  Matrixlas clases, podemos ver que hay muchas cosas que podemos utilizar para ayudarnos a trazar gráficos en la pantalla! Asegúrese de incluir KTX para tener una experiencia aún más fluida cuando trabaje con las clases de gráficos de Android.

Últimos de Foro (1)
Nuevos Post
Publicidad
Chileguía

El directorio en línea más completo para encontrar detalles de negocios, contactos, productos, servicios y precios.

info@chileguia.cl

© Chileguia. Todos los derechos reservados.
Implementado por Chileguia