Работа с изображениями. Элемент Image

Последнее обновление: 10.01.2021

Для вывода изображение имеется элемент Image. Но перед выводом изображения его надо добавить в проекты, причем в проект для каждой отдельной ос.

Локальные изображения

Добавление для Android

Возьмем какое-нибудь изображение. В проекте для Android добавим файл изображения в папку Resources/Drawable. А в окне Properties установим у этого изображения Build Action: AndroidResource.

Images in Xamarin for Android

Добавление для iOS

Также добавим изображение в проект для iOS. Для этого в проекте для iOS перейдем к папке Assets Catalogs. По умолчанию в ней должен быть каталог Assets. Нажем на него.

Images in Xamarin in iOS

В открывшмся окне нажмем на кнопку добавления нового набора ресурсов и выберем Add Image Sets

Далее нам откроется окно с прямоугольными областями для эскизов изображений. Нажмем в одной из прямоугольных областей на кнопку в правом верхнем углу и открывшемся после этого диалоговом окне выберем нужный файл изображения:

Images in Xamarin Forms iOS Image Sets

Проект UWP

Для проекта для UWP изображение просто добавляется в корневую папку проекта, а в окне свойств устанавливаем для изображения Build Action: Content. В итоге получится следующее:

Images in Xamarin

Доступ к изображению

А простейший код вывода изображения в элемент Image будет выглядеть так:

class MainPage : ContentPage
{
    public MainPage()
    {
        Image image = new Image { Source = "dubi.png" };
        this.Content = image;
    }
}

Аналог в xaml:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="HelloApp.MainPage">
  <Image Source="dubi.png" />
</ContentPage>
Вывод изображений в Xamarin Forms

В то же время такой подход может быть неудобен. Например, не очень было бы хорошо захломлять проект для UWP файлами и изображений, и вполне вероятно что мы бы предпочли создать в проекте специальную папку, к примеру, Images. А в нее уже добавлять файлы изображений. Однако в этом случае у нас была бы рассинхронизация в путях к файлу изображений. Так, в Android путь был бы по прежнему cat.jpg, а в для проекта для UWP - images/dubi.png.

И если пути к изображению отличаются в засимости от операционной системы, то мы могли бы проверить тип текущей платформы и зависимости от результатов проверки установить соответствующий путь:

Image image = new Image();
image.Source = Device.RuntimePlatform == Device.UWP ? "Images/dubi.png" : "dubi.png";

Размеры изображений

При использовании изображений надо учитывать размеры устройств. Например, для смартфона было бы не очень оптимально использовать изображение шириной 1000 пикселей. Возможно, такое изображение следует масштабировать, чтобы оно более оптимально выглядело на данном типе устройств.

На разных платформах есть свои принципы создания изображений для устройств с разной шириной экрана.

В Android применяется следующий подход: здесь файл надо положить в одну из подпапок в каталоге Resources:

  • drawable-hdpi: для устройств с расширением 240 DPI

  • drawable-xhdpi: для устройств с расширением 320 DPI

  • drawable-xxhdpi: для устройств с расширением 480 DPI

  • drawable-xxxhdpi: для устройств с расширением 640 DPI

К примеру, если у нас есть файл "wild.png", то для разных размеров можно определить несколько версий файла и положить их в соответствующую папку:

  • drawable-hdpi/wild.png - шириной и высотой в 240 пикселей

  • drawable-xhdpi/wild.png - шириной и высотой в 320 пикселей

  • drawable-xxhdpi/wild.png - шириной и высотой в 480 пикселей

  • drawable-xxxhdpi/wild.png - шириной и высотой в 640 пикселей

В UWP к имени файла можно добавить суффикс .scale-xxx перед расширением файла, где xxx представляет процент масштабирования, применяемый к ресурсу, напримео, wild.scale-200.png.

Embedded images

Встроенные изображения (embedded images) в отличие от выше рассмотренных локальных изображений добавляются непосредственно в разделяемую сборку в качестве ресурса. То есть нам надо добавить файл только в главный проект.

Так, создадим в главном проекте новый каталог Images и добавим в него файл изображения:

Embedded images in Xamarin Forms

После добавления изображения в панели свойств для поля Build Action установим значение Embedded Resources.

Выведем изображение в коде C#:

public partial class MainPage : ContentPage
{
    public MainPage()
    {
        Image image = new Image();
        image.Source = ImageSource.FromResource("HelloApp.Images.forest.jpg");
        Content = image;
    }  
}

Для получения ресурса изображения применяется метод ImageSource.FromResource(). Обратите внимание на путь, который в него передается. Этот путь начинается с названия проекта, то есть HelloApp. Дальше идет путь к изображению внутри проекта. Название проекта и название папок в этом пути отделяются точками.

Для XAML по умолчанию подобная возможность отсутствует, и нам надо вручную писать специальное расширение для XAML, которое позволит транслировать строковый путь в нужный нам объект.

Для этого добавим в проект следующий класс:

using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

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

        public object ProvideValue(IServiceProvider serviceProvider)
        {
            if (Source == null)
            {
                return null;
            }
            var imageSource = ImageSource.FromResource(Source);

            return imageSource;
        }
    }
}

Применим класс для загрузки изображения в коде xaml:

<?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:HelloApp;assembly=HelloApp"
             x:Class="HelloApp.MainPage">
    <Image Source="{local:ImageResource HelloApp.Images.forest.jpg}" />
</ContentPage>

Загрузка из сети

Кроме локальных картинок Xamarin также поддерживает загрузку из сети:

Image image = new Image();
image.Source = new UriImageSource 
{ 
    CachingEnabled = false,
    Uri = new System.Uri("http://www.someserver/someimage.png") 
};

Кроме url изображения также можно задать параметры кэширования. Выражение CachingEnabled = false отключает кэширование. Но мы также можем включить его и установить период кэширования:

Image image = new Image();
image.Source = new UriImageSource 
{ 
    CachingEnabled = true,
    CacheValidity = new System.TimeSpan(2,0,0,0),
    Uri = new System.Uri("http://www.someserver/someimage.png") 
};

Параметр CacheValidity указывает, сколько будет действовать кэширование - в данном случае 2 дня. Без установки параметра по умолчанию кэширование длится 24 часа.

Свойство Aspect

Свойство Aspect позволяет задать принцип масштабирования изображения при его выводе на экран. Это свойство в качестве значения принимает одну из констант из одноименного перечисления Aspect:

  • AspectFit: значение по умолчанию. Если стандартное изображение не вписывается в экран (например, его ширина больше ширины экрана), то оно масштабируется с сохранением аспектного отношения (отношение ширины к длине)

  • Fill: растягивает изображение по ширине или длине без сохрнения аспектного отношения

  • AspectFill: сохраняет аспектное отношение, но вырезает из него ту часть, которая вписывается в экран

Выше на рисунке демонстрировалось значение по умолчанию - AspectFit. Теперь попробуем AspectFill:

<Image Source="forest.jpg" Aspect="AspectFill" />

В итоге результат будет несколько отличаться:

Аспектное отношение изображений в Xamarin Forms
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850