Для вывода изображение имеется элемент Image. Но перед выводом изображения его надо добавить в проекты, причем в проект для каждой отдельной ос.
Возьмем какое-нибудь изображение. В проекте для Android добавим файл изображения в папку Resources/Drawable. А в окне Properties установим у этого изображения Build Action: AndroidResource.
Также добавим изображение в проект для iOS. Для этого в проекте для iOS перейдем к папке Assets Catalogs. По умолчанию в ней должен быть каталог Assets. Нажем на него.
В открывшмся окне нажмем на кнопку добавления нового набора ресурсов и выберем Add Image Sets
Далее нам откроется окно с прямоугольными областями для эскизов изображений. Нажмем в одной из прямоугольных областей на кнопку в правом верхнем углу и открывшемся после этого диалоговом окне выберем нужный файл изображения:Для проекта для UWP изображение просто добавляется в корневую папку проекта, а в окне свойств устанавливаем для изображения Build Action: Content. В итоге получится следующее:
А простейший код вывода изображения в элемент 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>
В то же время такой подход может быть неудобен. Например, не очень было бы хорошо захломлять проект для 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) в отличие от выше рассмотренных локальных изображений добавляются непосредственно в разделяемую сборку в качестве ресурса. То есть нам надо добавить файл только в главный проект.
Так, создадим в главном проекте новый каталог Images и добавим в него файл изображения:
После добавления изображения в панели свойств для поля 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:
AspectFit
: значение по умолчанию. Если стандартное изображение не вписывается в экран (например, его ширина больше ширины экрана),
то оно масштабируется с сохранением аспектного отношения (отношение ширины к длине)
Fill
: растягивает изображение по ширине или длине без сохрнения аспектного отношения
AspectFill
: сохраняет аспектное отношение, но вырезает из него ту часть, которая вписывается в экран
Выше на рисунке демонстрировалось значение по умолчанию - AspectFit. Теперь попробуем AspectFill:
<Image Source="forest.jpg" Aspect="AspectFill" />
В итоге результат будет несколько отличаться: