Cambios de coordenadas de transformación de iOS

Cuando se usa CGContext, las coordenadas de Quartz 2D y UIKit son inconsistentes, por lo que el contexto debe cambiarse nuevamente para lograr el efecto deseado.

1. Introducción al origen de diferentes coordenadas
En Quartz 2D, el origen de las coordenadas está en la esquina inferior izquierda del lienzo, mientras que en UIKit, es consistente con las coordenadas de la pantalla, y la esquina superior izquierda es el origen de las coordenadas.

Si dibuja F con el punto (0, 0) como origen, se obtendrán los siguientes resultados en diferentes sistemas de coordenadas.
image.png
2. Conversión del sistema de coordenadas Quartz 2D y UIKit

2.1 Dibujo de UIImage

En el desarrollo de la interfaz de usuario de iOS, tome UIImage como ejemplo, haga un dibujo, establezca el marco de la imagen en (0, 0, 320, 320) y obtendrá la imagen de la derecha.

Si usa el siguiente código para leer la transformación del contexto, puede ver que esta transformación no es una matriz de identidad.

Cuadro CGRect = CGRectMake (0.0, 0.0, 720, 1280);
UIGraphicsBeginImageContext (frame.size);
CGContextRef context = UIGraphicsGetCurrentContext ();
CGAffineTransform contextTransform = CGContextGetCTM (contexto) ;;

La configuración de transformación aquí hará que el origen de coordenadas de Quartz 2D y UIKit coincida, lo que también facilita el dibujo de controles en UIKit. Para cambios en el sistema de coordenadas, consulte la figura siguiente.
image.png
Es por eso que si llama a CGContextDrawImage directamente en el contexto adquirido, obtendrá una imagen invertida.

但 如果 使用 UIImage 的 drawInRect 方法 , 文档 是 这么 写 的 :
Método de instancia
draw (in :)
Dibuja la imagen completa en el rectángulo especificado, escalando según sea necesario para que encaje.
Declaración
func draw (in rect: CGRect)
Parámetros
rect
El rectángulo (en el sistema de coordenadas del contexto gráfico) en el que se dibujará la imagen.
Discusión
Este método dibuja la imagen completa en el contexto gráfico actual, respetando la configuración de orientación de la imagen. En el sistema de coordenadas predeterminado, las imágenes están situadas hacia abajo ya la derecha del origen del rectángulo especificado. Sin embargo, este método respeta cualquier transformación aplicada al contexto gráfico actual.
Este método dibuja la imagen con total opacidad usando el modo de mezcla CGBlendMode.normal.

En otras palabras, las coordenadas utilizadas cuando se dibuja UIImage siguen siendo las coordenadas internas de UIKit, por lo que no es necesario realizar ningún cambio en el sistema de coordenadas, y puede dibujar una imagen con la misma posición que el rect. Por supuesto, este método también dibujará de acuerdo con la orientación de la imagen.

2.2 Dibujo CGContextDrawImage

Al cambiar la transformación del contexto, lo que realmente está cambiando es el sistema de coordenadas en sí.

Al llamar al método de dibujo, se utilizan las coordenadas internas del sistema de coordenadas, por lo que cuando queremos dibujar una imagen mostrada por UIKit en base al contexto adquirido, también necesitamos ajustar el sistema de coordenadas antes de dibujar.

// Volteo del eje Y
CGContextScaleCTM (contexto, 1, -1);

// El origen de la imagen debe alinearse con la esquina superior izquierda y la altura de la imagen debe trasladarse hacia abajo en el eje Y
CGContextTranslateCTM (context, 0, -imageSize.height);

// Dibujar una imagen
CGContextDrawImage (contexto, marco, imagen.CGImage);
image.png

3 Transformar cambios en el punto de ancla Por
ejemplo, en la página de edición de imágenes, a menudo podemos encontrar cambios como hacer zoom, rotar y desplazar la imagen usando gestos y luego generar una nueva imagen.

De acuerdo con diferentes devoluciones de llamada de gestos, podemos modificar view.transform para hacer que la vista en la interfaz cambie correspondiente al gesto.

Aquí, para facilitarnos la modificación de la interfaz UI de UIKit, la transformación de la vista está anclada con el centro de la vista.

La descripción en la transformación de UIView es usar el centro para modificar la posición.

Utilice esta propiedad para escalar o rotar el rectángulo del marco de la vista dentro del sistema de coordenadas de su supervista. (Para cambiar la posición de la vista, modifique la propiedad del centro). El valor predeterminado de esta propiedad es CGAffineTransformIdentity.

Cuando se llaman muchos otros métodos, la transformación necesita usar la esquina superior izquierda como punto de ancla, por lo que debe haber una transformación aquí El punto de ancla afecta a la siguiente figura.
image.png
En la modificación de la interfaz de la interfaz de usuario, podemos usar los valores de devolución de llamada de los gestos de zoom y rotación para modificar directamente la transformación de la vista, y la devolución de llamada de desplazamiento para modificar el centro, y podemos lograr el efecto deseado. Pero esta transformación no se puede utilizar para el dibujo de contexto, porque el sistema de coordenadas se cambia con el origen como punto de ancla.

Por lo tanto, para la posición del sistema de coordenadas existente del contexto, el punto de anclaje está en la esquina superior izquierda y se requiere una modificación de transformación.

Según la figura anterior, se puede ver que el punto de ancla solo afecta la información de posición y no cambia el zoom y la rotación.

UIImage * image; // Inicializar la imagen

UIView * view; // Aplique la vista modificada, y el tamaño de la vista debe ser coherente con la imagen para garantizar que la relación de zoom sea correcta.

CGAffineTransform transform = view.transform;
CGSize imageSize = image.size;
transform.tx = view.center.x;
transform.ty = view.center.y;
transform = CGAffineTransformTranslate (transform, -imageSize.width * 0.5, -imageSize.height * 0.5);

Donde tx, ty son la posición del punto de ancla en el sistema de coordenadas

El punto de ancla actual está en el centro de la vista, necesitamos cambiarlo a la esquina superior izquierda de la vista para que coincida con el origen del sistema de coordenadas. Donde * (imageSize.width * 0.5, imageSize.height * 0.5) * es la posición del punto de ancla en la imagen, y transform es la matriz de cambio cuando el punto de ancla está en la esquina superior izquierda de la vista.

4. Combine Transform
para obtener el resultado en el medio de la figura anterior en CGContext, no solo necesita aplicar el cambio de reducción en 1/2 y rotación de 45 grados, sino que también necesita ajustar.

Dije antes que la rotación de la aplicación CGContext se aplica al sistema de coordenadas, que es consistente con la rotación de la aplicación de vista en su propio sistema de coordenadas. Por lo tanto, cuando el sistema de coordenadas optimizado del CGContext obtenido directamente es también el origen en la esquina superior izquierda, podemos aplicar directamente la transformación calculada en el CGContext.

Posteriormente, debido a que el sistema de coordenadas se dibuja en función de su propio sistema de coordenadas, realice una ronda de inversión y desplazamiento del sistema de coordenadas para obtener el resultado final, similar a la operación en la figura siguiente.

image.png

Cabe señalar aquí que cada nuevo cambio se basa en el cambio anterior, por lo que existe un orden tanto para la vista como para la transformación del contexto, lo cual es consistente con la multiplicación de matrices y el orden afectará el resultado.

Supongo que te gusta

Origin blog.csdn.net/weixin_41191739/article/details/109722369
Recomendado
Clasificación