Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En este artículo se explica la diferencia entre píxeles físicos y píxeles independientes del dispositivo (DIP) y cómo se controla ppp (puntos por pulgada) en Win2D.
Win2D está diseñado de tal manera que muchas aplicaciones pueden ignorar esta distinción, ya que proporciona comportamientos predeterminados razonables que harán lo correcto cuando se ejecuten en dispositivos de ppp bajos y altos. Si tu aplicación tiene necesidades más especializadas, o si tienes una opinión diferente sobre lo que significa "valor predeterminado razonable", lee para obtener los detalles de gory...
¿Qué es PPP?
PPP significa "puntos por pulgada". Se trata de una medida aproximada de la densidad de píxeles de una pantalla de salida, como un monitor de equipo o una pantalla de teléfono. Cuanto mayor sea el valor de PPP, más pequeños componen la pantalla.
PPP es solo una medida aproximada porque no se puede confiar en todo el hardware de visualización para informar de información precisa. Algunos monitores de equipo no informan de PPP al sistema operativo en absoluto, o es posible que el usuario haya configurado su sistema para representar con un PPP diferente del hardware real (por ejemplo, para cambiar el tamaño de los elementos de texto de la interfaz de usuario). Las aplicaciones pueden usar PPP para elegir cómo se deben dibujar las cosas grandes, pero no deben confiar en ella como una medición física exacta del tamaño de pantalla.
Un valor de PPP de 96 se considera un valor predeterminado neutro.
¿Qué es un píxel?
Un píxel es un único punto coloreado. Las imágenes de gráficos informáticos se componen de muchos píxeles organizados en una cuadrícula bidimensional. Puede pensar en píxeles como los átomos de los que se crean todas las imágenes.
El tamaño físico de un píxel puede variar considerablemente de una pantalla a otra. Cuando un equipo está conectado a un monitor grande pero de baja resolución o pantalla externa, los píxeles pueden ser bastante grandes, pero en un teléfono con una pantalla de 1080p solo unos pocos pulgadas a través, los píxeles son pequeños.
En Win2D, siempre que vea una API que especifique una posición o un tamaño mediante tipos de datos enteros (o una estructura como BitmapSize que contenga enteros), esto significa que la API funciona en unidades de píxeles.
La mayoría de las API win2D funcionan con DIP en lugar de píxeles.
¿Qué es una DIP?
DIP significa "píxel independiente del dispositivo". Se trata de una unidad virtualizada que puede ser igual que, mayor o menor que un píxel físico.
La relación entre píxeles y DIP viene determinada por PPP:
pixels = dips * dpi / 96
Cuando PPP es de 96, los píxeles y los DIP son los mismos. Al usar ppp más altos, una sola DIP puede corresponder a más de un píxel (o partes de píxeles en el caso común en el que PPP no es un múltiplo exacto de 96).
La mayoría de las API de Windows Runtime, incluidas Win2D, usan DIP en lugar de píxeles. Esto tiene la ventaja de mantener gráficos aproximadamente el mismo tamaño físico independientemente de la pantalla en la que se ejecute una aplicación. Por ejemplo, si una aplicación especifica que un botón tiene un ancho de 100 DIP, cuando se ejecuta en un dispositivo de PPP alto, como un teléfono o un monitor de 4k, este botón se escalará automáticamente para tener más de 100 píxeles de ancho, por lo que sigue siendo un tamaño razonable que es posible para que el usuario haga clic en él. Si el tamaño del botón se especificó en píxeles, por otro lado, aparecería ridículamente pequeño en este tipo de pantalla de PPP alto, por lo que la aplicación tendría que hacer más trabajo para ajustar los diseños de forma diferente para cada tipo de pantalla.
En Win2D, siempre que vea una API que especifique una posición o un tamaño mediante tipos de datos de punto flotante (o estructuras como Vector2 o Tamaño que contengan valores de punto flotante), esto significa que la API funciona en DIP.
Para convertir entre DIP y píxeles, use los métodos ConvertDipsToPixels(Single, CanvasDpiRounding)
y ConvertPixelsToDips(Int32)
.
Recursos win2D que tienen PPP
Todos los recursos win2D que contienen una imagen de mapa de bits también tienen una propiedad de PPP asociada:
CanvasBitmap
CanvasRenderTarget
CanvasSwapChain
CanvasControl
CanvasVirtualControl
CanvasAnimatedControl
CanvasImageSource
Todos los demás tipos de recursos son independientes de PPP. Por ejemplo, se puede usar una sola CanvasDevice
instancia para dibujar en controles o rendertargets de muchos DPIs diferentes, por lo que el dispositivo no tiene ningún PPP propio.
Del mismo modo, CanvasCommandList
no tiene un PPP, ya que contiene instrucciones de dibujo vectorial en lugar de una imagen de mapa de bits. PPP solo entra en juego durante el proceso de rasterización, cuando la lista de comandos se dibuja en un rendertarget o control (que tienen PPP).
Control de PPP
Los controles Win2D (CanvasControl
y CanvasVirtualControl
CanvasAnimatedControl
) usan automáticamente el mismo PPP que la pantalla en la que se ejecuta la aplicación. Esto coincide con el sistema de coordenadas usado por XAML, CoreWindow y otras API de Windows Runtime.
Si cambia el VALOR de PPP (por ejemplo, si la aplicación se mueve a una pantalla diferente), el control generará el CreateResources
evento y pasará un CanvasCreateResourcesReason
de DpiChanged
. Las aplicaciones deben responder a este evento recreando los recursos (como rendertargets) que dependen del PPP del control.
Rendertarget PPP
Las cosas que se pueden dibujar en (que incluye no solo CanvasRenderTarget
, sino también los tipos CanvasSwapChain
similares a rendertarget y CanvasImageSource
) tienen un PPP propio, pero a diferencia de los controles que estos tipos no están conectados directamente a una pantalla, por lo que Win2D no puede determinar automáticamente cuál debe ser el PPP. Si está dibujando en un rendertarget que se copiará más adelante en la pantalla, es probable que desee que rendertarget use el mismo PPP que la pantalla, pero si está dibujando para algún otro propósito (por ejemplo, generar imágenes para cargar en un sitio web), un valor predeterminado de 96 PPP sería más adecuado.
Para facilitar estos dos patrones de uso, Win2D proporciona dos tipos de sobrecarga de constructor:
CanvasRenderTarget(ICanvasResourceCreator, width, height, dpi)
CanvasRenderTarget(ICanvasResourceCreatorWithDpi, width, height)
La ICanvasResourceCreator
interfaz se implementa mediante CanvasDevice
, así como los controles Win2D. Dado que un dispositivo no tiene ningún PPP específico propio, debe especificar explícitamente el PPP al crear un rendertarget a partir de uno.
Por ejemplo, para crear un rendertarget de PPP predeterminado, donde los DIP y píxeles siempre serán lo mismo:
const float defaultDpi = 96;
var rtWithFixedDpi = new CanvasRenderTarget(canvasDevice, width, height, defaultDpi);
ICanvasResourceCreatorWithDpi
se ICanvasResourceCreator
extiende agregando una propiedad PPP. Los controles Win2D implementan esta interfaz y facilita la creación de un rendertarget que heredará automáticamente el mismo PPP que el control desde el que se creó:
var rtWithSameDpiAsDisplay = new CanvasRenderTarget(canvasControl, width, height);
PPP de mapa de bits
CanvasBitmap
, a diferencia de rendertarget, no hereda automáticamente PPP de un control. Los métodos para crear y cargar mapas de bits incluyen sobrecargas para especificar explícitamente PPP, pero si se deja fuera, el valor predeterminado de PPP de mapa de bits es 96 independientemente de la configuración de visualización actual.
La razón por la que los mapas de bits son diferentes a otros tipos es que son un origen de datos de entrada, en lugar de una salida en la que se dibujará. Por lo tanto, lo importante para los mapas de bits no es el PPP de dónde terminará esa salida, pero el PPP de la imagen de origen, que no está totalmente relacionado con la configuración de visualización actual.
Si carga un mapa de bits de PPP predeterminado de 100x100 y, a continuación, lo dibuja en un rendertarget, el mapa de bits se escalará de 100 DIP a 96 PPP (que es de 100 píxeles) a 100 DIP en el PPP del rendertarget de destino (que podría ser un mayor número de píxeles si es un rendertarget de PPP alto). La imagen resultante siempre tendrá un tamaño de 100 DIP (por lo que no habrá sorpresas desagradables en el diseño), pero puede sufrir algún desenfoque si se escale un mapa de bits de origen de PPP bajo hasta un destino de PPP superior.
Para mayor claridad en ppp altos, es posible que algunas aplicaciones deseen proporcionar varios conjuntos de imágenes de mapa de bits en diferentes resoluciones y, en tiempo de carga, seleccione la versión que mejor coincida con el PPP del control de destino. Es posible que otras aplicaciones prefieran enviar solo mapas de bits de PPP altos y permitir que Win2D escale verticalmente cuando se ejecute en pantallas de PPP inferiores (el escalado vertical a menudo puede parecer mejor que el escalado vertical). En cualquier caso, el ppp del mapa de bits se puede especificar como un parámetro para LoadAsync(ICanvasResourceCreator, String, Single)
.
Tenga en cuenta que algunos formatos de archivo de mapa de bits contienen metadatos de PPP propios, pero Win2D omite esto, ya que a menudo se establece incorrectamente. En su lugar, se debe especificar PPP explícitamente al cargar el mapa de bits.
CanvasDrawingSession PPP
CanvasDrawingSession
hereda su PPP de cualquier control, rendertarget, swapchain, etcetera, en el que se dibuja.
De forma predeterminada, todas las operaciones de dibujo funcionan en DIP. Si prefiere trabajar en píxeles, se puede cambiar a través de la Units
propiedad .
Ppp de efecto
La canalización de efectos de imagen hereda su PPP de cualquier CanvasDrawingSession
efecto que se dibuje. Internamente, el procesamiento de efectos siempre funciona en píxeles. Los valores de parámetro, como tamaños o posiciones, se especifican en DIP, pero estas unidades se convierten en píxeles antes de que se produzca cualquier manipulación de imágenes real.
Cuando se usa un mapa de bits de PPP diferente de la sesión de dibujo de destino como imagen de origen de efecto, se inserta automáticamente un elemento interno DpiCompensationEffect
entre el mapa de bits y el efecto. Esto escala el mapa de bits para que coincida con el PPP de destino, que suele ser lo que desea. Si no es lo que desea, puede insertar su propia instancia de DpiCompensationEffect
para personalizar el comportamiento.
Nota:
Si implementa un efecto personalizado, considere la posibilidad de aplicar un esquema de control de PPP equivalente para garantizar un comportamiento coherente cuando se usa junto con efectos Win2D integrados.
Composition API
Las Microsoft.Graphics.Canvas.Composition
API funcionan en un nivel inferior a los controles XAML de Win2D, por lo que no intentan controlar automáticamente ppp en su nombre. Es necesario decidir en qué unidades prefiere operar y establecer las transformaciones necesarias para lograrlo como parte del árbol visual de composición.
Windows.UI.Composition
Las API como CreateDrawingSurface
siempre especifican tamaños en unidades de píxel. Al usar Win2D para dibujar en una superficie de composición, puedes especificar cualquier PPP que quieras usar al llamar a CreateDrawingSession(CompositionDrawingSurface, Rect, Single)
. Todos los dibujos realizados a través del devuelto CanvasDrawingSession
se escalarán o reducirán verticalmente según corresponda.
Cómo probar el control de PPP
La manera más fácil de probar que la aplicación hará lo correcto en respuesta al cambio de PPP de pantalla es ejecutarse en Windows 10 o Windows 11 y cambiar la configuración de visualización mientras se ejecuta la aplicación:
- Haga clic con el botón derecho en el fondo del escritorio y elija "Mostrar configuración".
- Mueva el control deslizante con la etiqueta "Cambiar el tamaño del texto, las aplicaciones y otros elementos".
- Haga clic en el botón "Aplicar".
- Elija "Cerrar sesión más adelante"
Si no tiene Windows 10 o Windows 11, también puede probar con el simulador de Windows. En la barra de herramientas de Visual Studio, cambie la configuración "Máquina local" a "Simulador" y, a continuación, use el icono Cambiar resolución para cambiar la pantalla simulada entre:
- 100% (PPP = 96)
- 140 % (PPP = 134,4)
- 180 % (PPP = 172,8)