Imágenes en Xamarin.Forms

Descargar ejemploDescargar el ejemplo

Las imágenes se pueden compartir entre plataformas con Xamarin.Forms, se pueden cargar específicamente para cada plataforma o se pueden descargar para su visualización.

Las imágenes son una parte fundamental de la navegación, la facilidad de uso y la personalización de marca de la aplicación. Xamarin.Forms Las aplicaciones deben poder compartir imágenes en todas las plataformas, pero también mostrar imágenes diferentes en cada plataforma.

Las imágenes específicas de la plataforma también son necesarias para iconos y pantallas de presentación; deben configurarse por plataforma.

Mostrar imágenes

Xamarin.Forms usa la Image vista para mostrar imágenes en una página. Tiene varias propiedades importantes:

  • Source - Una ImageSource instancia, ya sea File, URI o Resource, que establece la imagen que se va a mostrar.
  • Aspect - Cómo ajustar el tamaño de la imagen dentro de los límites en los que se muestra (ya sea para estirar, recortar o cuadro de letras).

ImageSource Las instancias se pueden obtener mediante métodos estáticos para cada tipo de origen de imagen:

  • FromFile - Requiere un nombre de archivo o una ruta de acceso de archivo que se pueda resolver en cada plataforma.
  • FromUri - Requiere un objeto URI, por ejemplo, new Uri("http://server.com/image.jpg") .
  • FromResource - Requiere un identificador de recurso para un archivo de imagen incrustado en la aplicación o en el proyecto de biblioteca de .NET Standard, con una acción de compilación:EmbeddedResource.
  • FromStream - Requiere una secuencia que proporciona datos de imagen.

La Aspect propiedad determina cómo se escalará la imagen para ajustarse al área de presentación:

  • Fill - Estira la imagen para rellenar completamente y exactamente el área de visualización. Esto puede dar lugar a que la imagen se distorsiona.
  • AspectFill - Recorta la imagen para que llene el área de visualización a la vez que conserva el aspecto (es decir, sin distorsión).
  • AspectFit - Letterboxes la imagen (si es necesario) para que toda la imagen se ajuste al área de visualización, con espacio en blanco agregado a la parte superior/inferior o lateral dependiendo de si la imagen es ancha o alta.

Las imágenes se pueden cargar desde un archivo local, un recurso incrustado, descargado o cargado desde una secuencia. Además, la Image vista puede mostrar los iconos de fuente especificando los datos del icono de fuente en un FontImageSource objeto . Para obtener más información, vea Mostrar iconos de fuente en la guía Fuentes .

Imágenes locales

Los archivos de imagen se pueden agregar a cada proyecto de aplicación y hacer referencia a ellos desde Xamarin.Forms código compartido. Este método de distribución de imágenes es necesario cuando las imágenes son específicas de la plataforma, por ejemplo, al usar resoluciones diferentes en plataformas diversas, o bien al emplear diseños que difieren ligeramente.

Para usar una sola imagen en todas las aplicaciones, se debe usar el mismo nombre de archivo en todas las plataformas y debe ser un nombre de recurso de Android válido (es decir, solo se permiten letras minúsculas, números, el carácter de subrayado y el punto).

  • iOS : la manera preferida de administrar y admitir imágenes, ya que iOS 9 es usar conjuntos de imágenes del catálogo de activos, que deben contener todas las versiones de una imagen que son necesarias para admitir varios dispositivos y factores de escala para una aplicación. Para obtener más información, vea Agregar imágenes a un conjunto de imágenes del catálogo de activos.
  • Android : coloque imágenes en el directorio Resources/drawable con Build Action: AndroidResource. También se pueden proporcionar versiones de valores altos y bajos de ppp de una imagen (en subdirectorios De recursos, como drawable-ldpi, drawable-hdpi y drawable-xhdpi).
  • Plataforma universal de Windows (UWP): de forma predeterminada, las imágenes deben colocarse en el directorio raíz de la aplicación con Acción de compilación: Contenido. Como alternativa, las imágenes se pueden colocar en un directorio diferente que, a continuación, se especifica con una plataforma específica. Para obtener más información, consulte Directorio de imágenes predeterminado en Windows.

Importante

Antes de iOS 9, las imágenes se colocaban normalmente en la carpeta Resources con Acción de compilación: BundleResource. Sin embargo, Apple ha dejado de usar este método para trabajar con imágenes en una aplicación iOS. Para obtener más información, vea Tamaños de imagen y nombres de archivo.

La adhesión a estas reglas para la nomenclatura y colocación de archivos permite que el código XAML siguiente cargue y muestre la imagen en todas las plataformas:

<Image Source="waterfront.jpg" />

El código de C# equivalente es el siguiente:

var image = new Image { Source = "waterfront.jpg" };

En las capturas de pantalla siguientes se muestra el resultado de mostrar una imagen local en cada plataforma:

Aplicación de ejemplo que muestra una imagen local

Para obtener más flexibilidad, la Device.RuntimePlatform propiedad se puede usar para seleccionar un archivo o ruta de acceso de imagen diferente para algunas o todas las plataformas, como se muestra en este ejemplo de código:

image.Source = Device.RuntimePlatform == Device.Android
                ? ImageSource.FromFile("waterfront.jpg")
                : ImageSource.FromFile("Images/waterfront.jpg");

Importante

Para usar el mismo nombre de archivo de imagen en todas las plataformas, el nombre debe ser válido en todas las plataformas. Los drawables de Android tienen restricciones de nomenclatura ( solo se permiten letras minúsculas, números, caracteres de subrayado y punto) y, para la compatibilidad multiplataforma, esto también debe seguirse en todas las demás plataformas. El nombre de archivo de ejemplo waterfront.png sigue las reglas, pero algunos ejemplos de nombres de archivo no válidos incluyen "water front.png", "WaterFront.png", "water-front.png" y "wåterfront.png".

Resoluciones nativas (retina y valores altos de PPP)

iOS, Android y UWP incluyen compatibilidad con diferentes resoluciones de imagen, donde el sistema operativo elige la imagen adecuada en tiempo de ejecución en función de las funcionalidades del dispositivo. Xamarin.Forms usa las API de las plataformas nativas para cargar imágenes locales, por lo que admite automáticamente resoluciones alternativas si los archivos se denominan correctamente y se encuentran en el proyecto.

La manera preferida de administrar imágenes, ya que iOS 9 es arrastrar imágenes para cada resolución necesaria al conjunto de imágenes del catálogo de recursos adecuado. Para obtener más información, vea Agregar imágenes a un conjunto de imágenes del catálogo de activos.

Antes de iOS 9, las versiones de retina de la imagen se podían colocar en la carpeta Resources : dos y tres veces la resolución con un @2x o @3x sufijos en el nombre de archivo antes de la extensión de archivo (por ejemplo myimage@2x.png, ). Sin embargo, Apple ha dejado de usar este método para trabajar con imágenes en una aplicación iOS. Para obtener más información, vea Tamaños de imagen y nombres de archivo.

Las imágenes de resolución alternativa de Android deben colocarse en directorios con nombre especial en el proyecto de Android, como se muestra en la captura de pantalla siguiente:

Ubicación de la imagen de resolución múltiple de Android

Los nombres de archivo de imagen de UWP se pueden sufijar antes .scale-xxx de la extensión de archivo, donde xxx es el porcentaje de escalado aplicado al recurso, por ejemplo ,myimage.scale-200.png. A continuación, se puede hacer referencia a imágenes en código o XAML sin el modificador de escala, por ejemplo, simplemente myimage.png. La plataforma seleccionará la escala de recursos más cercana adecuada en función del valor de PPP actual de la pantalla.

Controles adicionales que muestran imágenes

Algunos controles tienen propiedades que muestran una imagen, como:

  • Buttontiene una ImageSource propiedad que se puede establecer en una imagen de mapa de bits que se va a mostrar en .Button Para obtener más información, vea Uso de mapas de bits con botones.

  • ImageButtontiene una Source propiedad que se puede establecer en la imagen que se va a mostrar en .ImageButton Para obtener más información, consulte Establecimiento del origen de la imagen.

  • ToolbarItem tiene una IconImageSource propiedad que se puede establecer en una imagen que se carga desde un archivo, un recurso incrustado, un URI o una secuencia.

  • ImageCell tiene una ImageSource propiedad que se puede establecer en una imagen recuperada de un archivo, un recurso incrustado, un URI o una secuencia.

  • Page. Cualquier tipo de página que derive de Page tiene IconImageSource propiedades y BackgroundImageSource , que se pueden asignar a un archivo, un recurso incrustado, un URI o una secuencia. En determinadas circunstancias, como cuando NavigationPage se muestra un ContentPage, el icono se mostrará si es compatible con la plataforma.

    Importante

    En iOS, la Page.IconImageSource propiedad no se puede rellenar a partir de una imagen de un conjunto de imágenes del catálogo de recursos. En su lugar, cargue imágenes de icono para la Page.IconImageSource propiedad desde un archivo, un recurso incrustado, un URI o una secuencia.

Imágenes incrustadas

Las imágenes incrustadas también se incluyen con una aplicación (como imágenes locales), pero en lugar de tener una copia de la imagen en la estructura de archivos de cada aplicación, el archivo de imagen se incrusta en el ensamblado como un recurso. Este método de distribución de imágenes se recomienda cuando se usan imágenes idénticas en cada plataforma y es especialmente adecuada para crear componentes, ya que la imagen se agrupa con el código.

Para insertar una imagen en un proyecto, haga clic con el botón derecho para agregar nuevos elementos y seleccione las imágenes que desea agregar. De forma predeterminada, la imagen tendrá Acción de compilación: Ninguna; debe establecerse en Acción de compilación: EmbeddedResource.

Establecimiento de la acción de compilación en un recurso incrustado

La acción de compilación se puede ver y cambiar en la ventana Propiedades de un archivo.

En este ejemplo, el identificador de recurso es WorkingWithImages.beach.jpg. El IDE ha generado este valor predeterminado mediante la concatenación del espacio de nombres predeterminado para este proyecto con el nombre de archivo, usando un punto (.) entre cada valor.

Si coloca imágenes insertadas en carpetas dentro del proyecto, los nombres de carpeta también se separan por puntos (.) en el identificador de recurso. Mover la imagen debeach.jpg a una carpeta denominada MyImages daría lugar a un identificador de recurso de WorkingWithImages.MyImages.beach.jpg

El código para cargar una imagen insertada simplemente pasa el identificador de recurso al ImageSource.FromResource método, como se muestra a continuación:

Image embeddedImage = new Image
{
    Source = ImageSource.FromResource("WorkingWithImages.beach.jpg", typeof(MyClass).GetTypeInfo().Assembly)
};

Nota

Para admitir la visualización de imágenes incrustadas en modo de versión en el Plataforma universal de Windows, es necesario usar la sobrecarga de que especifica el ensamblado de ImageSource.FromResource origen en el que se va a buscar la imagen.

Actualmente no hay ninguna conversión implícita para los identificadores de recursos. En su lugar, debe usar ImageSource.FromResource o new ResourceImageSource() para cargar imágenes incrustadas.

En las capturas de pantalla siguientes se muestra el resultado de mostrar una imagen insertada en cada plataforma:

Aplicación de ejemplo que muestra una imagen insertada

XAML

Dado que no hay ningún convertidor de tipos integrado de string a ResourceImageSource, XAML no puede cargar de forma nativa estos tipos de imágenes. En su lugar, se puede escribir una extensión de marcado XAML personalizada sencilla para cargar imágenes mediante un identificador de recurso especificado en XAML:

[ContentProperty (nameof(Source))]
public class ImageResourceExtension : IMarkupExtension
{
 public string Source { get; set; }

 public object ProvideValue (IServiceProvider serviceProvider)
 {
   if (Source == null)
   {
     return null;
   }

   // Do your translation lookup here, using whatever method you require
   var imageSource = ImageSource.FromResource(Source, typeof(ImageResourceExtension).GetTypeInfo().Assembly);

   return imageSource;
 }
}

Nota

Para admitir la visualización de imágenes incrustadas en modo de versión en el Plataforma universal de Windows, es necesario usar la sobrecarga de que especifica el ensamblado de ImageSource.FromResource origen en el que se va a buscar la imagen.

Para usar esta extensión, agregue un personalizado xmlns al CÓDIGO XAML con los valores de ensamblado y espacio de nombres correctos para el proyecto. A continuación, el origen de la imagen se puede establecer mediante esta sintaxis: {local:ImageResource WorkingWithImages.beach.jpg}. A continuación se muestra un ejemplo xaml completo:

<?xml version="1.0" encoding="UTF-8" ?>
<ContentPage
   xmlns="http://xamarin.com/schemas/2014/forms"
   xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
   xmlns:local="clr-namespace:WorkingWithImages;assembly=WorkingWithImages"
   x:Class="WorkingWithImages.EmbeddedImagesXaml">
 <StackLayout VerticalOptions="Center" HorizontalOptions="Center">
   <!-- use a custom Markup Extension -->
   <Image Source="{local:ImageResource WorkingWithImages.beach.jpg}" />
 </StackLayout>
</ContentPage>

Solución de problemas de imágenes incrustadas

Depurar código

Dado que a veces es difícil entender por qué no se carga un recurso de imagen determinado, el siguiente código de depuración se puede agregar temporalmente a una aplicación para ayudar a confirmar que los recursos están configurados correctamente. Generará todos los recursos conocidos insertados en el ensamblado especificado en la consola para ayudar a depurar problemas de carga de recursos.

using System.Reflection;
// ...
// NOTE: use for debugging, not in released app code!
var assembly = typeof(MyClass).GetTypeInfo().Assembly;
foreach (var res in assembly.GetManifestResourceNames())
{
    System.Diagnostics.Debug.WriteLine("found resource: " + res);
}

Imágenes insertadas en otros proyectos

De forma predeterminada, el ImageSource.FromResource método solo busca imágenes en el mismo ensamblado que el código que llama al ImageSource.FromResource método . Con el código de depuración anterior, puede determinar qué ensamblados contienen un recurso específico cambiando la typeof() instrucción a un Type conocido para que esté en cada ensamblado.

Sin embargo, el ensamblado de origen que se busca en una imagen incrustada se puede especificar como argumento para el ImageSource.FromResource método :

var imageSource = ImageSource.FromResource("filename.png",
            typeof(MyClass).GetTypeInfo().Assembly);

Descargar imágenes

Las imágenes se pueden descargar automáticamente para mostrarse, como se muestra en el código XAML siguiente:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
       x:Class="WorkingWithImages.DownloadImagesXaml">
  <StackLayout VerticalOptions="Center" HorizontalOptions="Center">
    <Label Text="Image UriSource Xaml" />
    <Image Source="https://aka.ms/campus.jpg" />
    <Label Text="campus.jpg gets downloaded from microsoft.com" />
  </StackLayout>
</ContentPage>

El código de C# equivalente es el siguiente:

var webImage = new Image {
     Source = ImageSource.FromUri(
        new Uri("https://aka.ms/campus.jpg")
     ) };

El ImageSource.FromUri método requiere un Uri objeto y devuelve un nuevo UriImageSource objeto que lee de Uri.

También hay una conversión implícita para las cadenas de URI, por lo que el ejemplo siguiente también funcionará:

webImage.Source = "https://aka.ms/campus.jpg";

En las capturas de pantalla siguientes se muestra el resultado de mostrar una imagen remota en cada plataforma:

Aplicación de ejemplo que muestra una imagen descargada

Almacenamiento en caché de imágenes descargado

También UriImageSource admite el almacenamiento en caché de imágenes descargadas, configuradas mediante las siguientes propiedades:

  • CachingEnabled - Indica si el almacenamiento en caché está habilitado (true de forma predeterminada).
  • CacheValidityTimeSpan: que define cuánto tiempo se almacenará la imagen localmente.

El almacenamiento en caché está habilitado de forma predeterminada y almacenará la imagen localmente durante 24 horas. Para deshabilitar el almacenamiento en caché de una imagen determinada, cree una instancia del origen de la imagen como se indica a continuación:

image.Source = new UriImageSource { CachingEnabled = false, Uri = new Uri("https://server.com/image") };

Para establecer un período de caché específico (por ejemplo, 5 días), cree una instancia del origen de la imagen como se indica a continuación:

webImage.Source = new UriImageSource
{
    Uri = new Uri("https://aka.ms/campus.jpg"),
    CachingEnabled = true,
    CacheValidity = new TimeSpan(5,0,0,0)
};

El almacenamiento en caché integrado facilita la compatibilidad con escenarios como el desplazamiento de listas de imágenes, donde puede establecer (o enlazar) una imagen en cada celda y permitir que la memoria caché integrada se ocupe de volver a cargar la imagen cuando la celda se desplaza hacia atrás en la vista.

GIF animados

Xamarin.Forms incluye compatibilidad para mostrar GIF pequeños y animados. Esto se logra estableciendo la Image.Source propiedad en un archivo GIF animado:

<Image Source="demo.gif" />

Importante

Aunque la compatibilidad con GIF animado en Xamarin.Forms incluye la capacidad de descargar archivos, no admite el almacenamiento en caché ni el streaming de GIF animados.

De forma predeterminada, cuando se carga un GIF animado, no se reproducirá. Esto se debe a que la IsAnimationPlaying propiedad , que controla si un GIF animado se está reproduciendo o detenido, tiene un valor predeterminado de false. Esta propiedad, de tipo bool, está respaldada por un BindableProperty objeto , lo que significa que puede ser el destino de un enlace de datos y con estilo.

Por lo tanto, cuando se carga un GIF animado, no se reproducirá hasta que la IsAnimationPlaying propiedad se establezca trueen . La reproducción se puede detener estableciendo la IsAnimationPlaying propiedad falseen . Tenga en cuenta que esta propiedad no tiene ningún efecto al mostrar un origen de imagen no GIF.

Nota

En Android, la compatibilidad con GIF animado requiere que la aplicación use representadores rápidos y no funcionará si ha optado por usar los representadores heredados. En UWP, la compatibilidad con GIF animado requiere una versión mínima de la actualización de aniversario de Windows 10 (versión 1607).

Iconos y pantallas de presentación

Aunque no está relacionado con la Image vista, los iconos de aplicación y las pantallas de presentación también son un uso importante de imágenes en Xamarin.Forms proyectos.

La configuración de iconos y pantallas de presentación para Xamarin.Forms las aplicaciones se realiza en cada uno de los proyectos de aplicación. Esto significa generar imágenes de tamaño correcto para iOS, Android y UWP. Estas imágenes deben denominarse y ubicarse según los requisitos de cada plataforma.

Iconos

Consulta las directrices de iOS Working with Images, Google Icongraphy y UWP guidelines for tile and icon assets for tile and icon assets (Directrices para trabajar con imágenes, Iconos de Google y UWP) para obtener más información sobre cómo crear estos recursos de aplicación.

Además, la Image vista puede mostrar los iconos de fuente especificando los datos del icono de fuente en un FontImageSource objeto . Para obtener más información, vea Mostrar iconos de fuente en la guía Fuentes .

Pantallas de presentación

Solo las aplicaciones de iOS y UWP requieren una pantalla de presentación (también denominada pantalla de inicio o imagen predeterminada).

Consulte la documentación para trabajar con imágenes y pantallas de presentación de iOS en el Centro de desarrollo de Windows.