Xamarin Image, как работать с изображениями в Xamarin

В любом приложении немаловажную роль играют изображения, применяемые повсеместно для упрощения навигации, повышения комфорта пользования, размещения логотипа фирмы. Отображаться эти картинки могут при этом совершенно по-разному в зависимости от платформы пользователя. К тому же, может быть иным сам тип изображения, например, значки или заставки, и каждый тип изображения будет отображаться иначе.

В приложениях, созданных на базе Xamarin.Forms, изображения должны совместно использоваться на любых современных платформах. Необходимо, чтобы каждая картинка выводилась одинаково на любой платформе и настраивалась под различные форматы отображения.

Отображение изображений в Xamarin

Элемент Image в Xamarin.Forms используется для задания основных параметров по отображению файлов изображений в приложении. Для этого у него присутствуют два свойства:

  • SourceImageSource — пример файла, ресурса или URI, предназначенный для отображения картинки.
  • Aspect – размер картинки в определённых границах и как его в них отображать: как растягивать, как обрезать или отрезать.

Файлы для Xamarin ImageSource размещаются через статические методы в зависимости от типа первоисточника изображения:

  • FromFile применяется при наличии доступа к файлу или пути к файлу, разрешённом для каждой платформы.
  • FromResource пользуется особым идентификатором каждого ресурса для получения изображения, располагаемого в проект или библиотеку .NET Standard с подключенной сборкой EmbeddedResource.
  • FromUri требуется для работы с объектами URI.
  • FromStream можно применить при наличии потока с файлами изображений.

Через свойство Aspect задаётся масштабирование изображения в отображаемой области:

  • Fill наполняет заданное пространство, растягивая изображения, пока область не будет полностью заполнена. Это свойство может искажать картинку.
  • AspectFill аналогично предыдущему наполняет область отображения, но вместо искажения изображения обрезает его, чтобы полностью вместить картинку без нарушения её формы.
  • AspectFit размещает изображение в заданную область вместе с пробелами, чтобы полностью наполнить область отображения без искажения или обрезания оригинального файла.

Изображения Xamarin можно скачивать из имеющегося локального источника, встроенного ресурсного каталога или из доступного к скачиванию и загрузке потока. Даже символы шрифта можно изменить на формат Image, изменив их на любые другие форматы, для этого необходимо указать данные шрифта в свойстве FontImageSource.

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

В каждый созданный проект приложения можно встраивать изображения и создавать ссылки к ним через код Xamarin.Forms. Все изображения необходимо прикреплять именно названным образом. Для применения выбранного изображения у всех программ на любой системе должно применяться единое название файла в дозволенном формате имени для Android — исключительно шрифтом в нижнем регистре, стандартными символами и цифрами.

  • iOS является рекомендуемым вариантом платформы для работы с образами, потому что она работает с наибольшим разнообразием библиотек и каталогов, требуемых для поддержки совместимости со всеми устройствами и корректного масштабирования изображений под приложения на конкретных устройствах. Дополнительные сведения см. в разделе "Добавление изображений в набор образов каталога активов".
  • Android способен помещать картинки в папку resources/drawable через специальный интерфейс с помощью назначенного действия. Ещё на платформе доступно размещение изображения с хорошим или плохим уровнем разрешения в конкретных каталогах ресурсов.
  • Универсальная платформа Windows (UWP) изначально располагает изображения в главном каталоге, но его можно изменить и в другом, указанном для конкретной платформы. Дополнительные сведения см. в каталоге изображений по умолчанию Windows.

До 9 версии iOS иллюстрации отправляются в ресурсную папку через действие BundleResource, однако данный способ сборки не рекомендуется разработчиками apple.

Соблюдение этих правил для именования и размещения файлов позволяет следующему XAML загружать и отображать изображение на всех платформах:

<image source="waterfront.jpg"></image><span>></span>

Эквивалентный код C# выглядит следующим образом:

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

На скриншотах далее продемонстрирован результат вывода изображения на iOS и Android:

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

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

Рекомендуется сразу давать файлу имя, доступное к применению на всех платформах. Так не возникнет проблем в дальнейшем при размещении изображения в разрабатываемом приложении. Например, картинки в Андроид имеют следующие лимиты: имя позволено создавать только из символов нижнего регистра, стандартных символов и цифр, обозначенных подчёркиваний. Запрещено применение пробелов, заглавных букв, тире, диакритиков и прочего. Например, использование имени файла waterfront.png подходит под правила. Следующие примеры недопустимых имен файлов включают: "water front.png", "WaterFront.png", "water-front.png" и "wåterfront.png".

Собственные разрешения (сетчатка и высокий уровень DPI)

Операционные системы работают с различающимися разрешениями картинок. IOS, Android и UWP во время работы приложения подбирают из предложенных подходящий образ для отображения подходящей картинки. При этом Xamarin.Forms автоматически выбирает правильное разрешение, используя собственные образы, но только в случае, когда файлы корректно поименованы и расположены.

Один из самых желательных вариантов обработки изображений в проекте программы — использовать iOS девятой версии или свежее, так как в нём можно просто перемещать иллюстрации путём перетаскивания их в каталог раздельно от остальных, что упрощает размещение картинок всех разрешений по относящимся ресурсам. Дополнительные сведения см. в разделе "Добавление изображений в набор образов каталога активов".

До девятой версии ресурсы размещались в одноимённой папке в нескольких копиях разного формата и выделялись с помощью специальных окончаний, например, @2x. Размещались эти окончания в конце названия изображения. Такой вариант работы признан устаревшим, и не рекомендуется разработчиками. Дополнительные сведения см. в разделе "Размеры изображений" и "Имена файлов".

Изображения альтернативного разрешения Android должны размещаться в специально именованных каталогах в проекте Android, как показано на следующем снимке экрана:

Для UWP имена файлов изображений формируются с использованием суффикса .scale-xxx перед расширением файла, где xxx процент масштабирования, примененного к ресурсу, например myimage.scale-200.png. Применение такой системы позволяет приложению на платформе автоматически выбирать наиболее подходящий масштаб изображения, основываясь на дисплее текущего устройства, поэтому в коде или XAML оставлять ссылку на файл разрешается без указания окончания.

Дополнительные элементы управления, отображающие изображения

Приведем примеры дополнительных элементов и их свойств:

  • ButtonImageSource является свойством, задающим параметры отображения у растровых иллюстраций.
  • ImagebuttonSource Xamarin Forms определяет изображение, в дальнейшем отображаемое с помощью ImageButton.
  • ToolbarItemIconImageSource занимается определением свойств образов.
  • ImageCellImageSource позволяет задавать свойства загруженных изображений из файла, URI, потока.
  • Page формирует вид любой страницы в зависимости от его типа, определяемого такими свойствами, как IconImageSource или BackgroundImageSource, назначаемых файлам или ресурсам.

На системе iOS есть ограничение, не позволяющее Page.IconImageSource применять к набору образов исполняемые ресурсы. Для обхода ограничения необходимо загружать все картинки, применяемые для значков, из сторонних источников.

Внедренные образы

Внедрённые образы обычно идут вместе с приложением, но без встроенных в сборку копий образа под каждую платформу. Применение такого способа размещения изображений рекомендуется в случаях, когда одинаковые файлы применяются на всех операционных системах. Особенно хорошо этот метод показывает себя при создании элементов для приложения.

Для размещения иллюстрации в проекте программы нужно прописать элемент EmbeddedResource. Изначально это действие является отключённым. Чтобы изменить это действие, нужно щёлкнуть по нему правой кнопкой мыши, нажать на добавление нового элемента, и выбрать нужное изображение.

Выбранное действие можно будет осмотреть или изменить позднее в свойствах самого файла.

В варианте выше идентифицируемым элементов ресурса является WorkingWithImages.beach.jpg. Интегрированная среда разработки по умолчанию задаёт ему значение через соединение нескольких названий внутри этого файла с самим файлом, используя при этом точку как разделитель между результирующими значениями.

При расположении внедрённых иллюстраций внутри папок в самом приложении их названия также должны быть разделены точками (.) для адекватной идентификации ресурса. Например, перенос beach.jpg в папку с названием MyImages создаст идентификатор для ресурса под названием WorkingWithImages.MyImages.beach.jpg.

Ниже продемонстрировано, как код для загрузки внедрённого изображения совершает передачу идентификатора для осуществления метода ImageSource.FromResource в отношении рабочего ресурса.

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

На универсальной платформе Windows для стабильного и корректного показа картинок из внедрённых файлов приходится обращаться к свойству ImageSource.FromResource, которое ссылается на базовую сборку, выполняющую поиск необходимого образа.

Поскольку у системы идентификации отсутствует вариант неявного преображения, единственным вариантом остаётся использование ImageSource.FromResource или newResourceImageSource() для загрузки нужных внедряемых образов.

На скриншотах далее продемонстрирован итог размещения внедрённого изображения и его демонстрационный показ на любой платформе:

XAML

Из-за отсутствия встроенных трансформаторов типа картинок stringResourceImageSource не имеет возможности загружаться в 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;
}
}

Для поддержки отображения внедренных изображений в режиме выпуска на универсальная платформа Windows необходимо использовать перегрузкуImageSource.FromResource, указывающую исходную сборку, в которой выполняется поиск образа.

Для применения вышеуказанного расширения в XAML добавляется собственный xmlns код. Для этого необходимо применять совместимые названия, варианты значения для пространств и версии сборки для программы, благодаря чему источник с иллюстрацией будет возможно задать следующим указанным вариантом: {local:ImageResource WorkingWithImages.beach.jpg}. Далее показан пример 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:WorkingWithImages;assembly=WorkingWithImages" x:class="WorkingWithImages.EmbeddedImagesXaml">
<stacklayout verticaloptions="Center" horizontaloptions="Center">
<!-- use a custom Markup Extension -->
<image source="{local:ImageResource WorkingWithImages.beach.jpg}"></image>
</stacklayout>
</contentpage>

Устранение неполадок внедренных образов

Отладка кода

Бывают случаи, когда корректно указанный ресурс изображения не прогружается. Для устранения этой проблемы применим описанный далее код отладки. Он отправляет любые знакомые проекту приложения файлы в специальную консоль, из которой можно наглядно изучить все проблемы с подгрузкой ресурсов. Это позволит убедиться, что настройки всех применённых ресурсов выставлены правильно.

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);
}

Изображения, внедренные в другие проекты

Изначально настройки выставлены таким образом, что поиск изображений через ImageSource.FromResource происходит только в сборке, в которой и прописан код, вызывающий метод поиска. Взяв описанный ранее код отладки и изменив инструкцию typeof() на прописанную для каждого типа сборки, становится возможным определить, что за ресурсы находятся во всех сборках. Но изначальную версию сборки, в которой ищется внедрёный образ, можно применять и для аргумента к ImageSource.FromResource следующим образом:

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

Скачивание изображений

В варианте кода XAML далее продемонстрировано, как изображения можно автоматизировано поставить на скачивание для дальнейшего отображения:

<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"></label>
 <image source="https://aka.ms/campus.jpg"></image>
 <label text="campus.jpg gets downloaded from microsoft.com"></label>
 </stacklayout>
</contentpage>

Аналогичный код в C# пишется таким способом:

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

Выше указан метод ImageSource.FromUri, которому необходимы именно URI объекты, и он будет возвращать новые объекты UriImageSource, которые он обнаруживает в самом URI. Однако, возможно также и неявное преображение строк URI, которое также является работоспособным:

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

На скриншотах далее продемонстрирован итог удалённого размещения изображения и его отображение на любой площадке:

Кэширование скачанных изображений

Применяя описанные далее свойства для настройки UriImageSource, можно проводить кеширование скаченных образов:

  • CachingEnabled сообщает о состоянии включения кеширования (true по умолчанию).
  • CacheValidity определяет показатель TimeSpan, которая задаёт срок локального хранения изображения.

Кеш включен по умолчанию, а сохранённые локальные образы хранятся сутки. Чтобы изменить настройки и выключить кеширование для изображения, впишите вариант источника таким методом:

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

Для определения иного периода хранения кеша (для примера будет 5 дней), создайте источник так, как написано далее:

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

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

Анимированные GIF-файлы

Xamarin.Forms позволяет встраивать малообъёмные изображения с расширением .gif со встроенной анимацией. Для использования таких файлов необходимо указать свойство Image.Source следующим образом:

<image source="demo.gif"></image>

Несмотря на то, что в Xamarin.Forms поддерживаются анимированные изображения и возможность их скачивания, кеширование или потоковая загрузка для файлов .gif отсутствует.

По умолчанию для IsAnimationPlaying указывается значение false, которое не дает файлу с расширением .gif начать самостоятельное воспроизведение. Для того, чтобы файл начал воспроизводиться, для IsAnimationPlaying необходимо указать значение true. При необходимости произведение анимации можно будет вновь прекратить, вернув изначальное значение false. Учтите, что описанное свойство работает только с GIF-файлами и не работает ни с какими другими изображениями.

На операционной системе Android существует дополнительная проблема в GIF-файлами. Для включения автоматического воспроизведения анимации необходимо, чтобы приложение использовало скоростные и современные программы отрисовки, в иных случаях анимированные изображения работать не будут. В случае же с UWP требуется наличие хотя бы версии 1607 для операционной системы Windows 10.

Значки и экраны-заставки

Значки и заставки считаются немаловажными при создании приложений. Хоть они и не связаны с темой Image, ни один проект на базе Xamarin.Forms не должен обходиться без применения этих картинок. Задание настроек и формата изображений для значков и заставок приложений должно выполняться во всех версиях приложений для каждой операционной системы индивидуально: все картинки для iOS, Андроид и UWP должны создаваться, называться и располагаться по всем требованиям этих операционных систем.

Экраны-заставки

Изображение вида экрана-заставки (начальный экран или изображение по умолчанию) требуется только для приложений на базе операционных систем iOS или UWP.

Ознакомьтесь с документацией по iOS, работающей с изображениями и экранами-заставкой на Windows Центр разработки.

Оглавление

Материалы по теме