Аннотация к главе 13. Растровые изображения
Примечание.
Эта книга была опубликована весной 2016 года и с тех пор не обновлялась. Многое в этой книге остается ценным, но некоторые материалы устарели, а некоторые разделы перестали быть полностью верными или полными.
Элемент Xamarin.FormsImage
отображает растровое изображение. Все платформы Xamarin.Forms поддерживают форматы файлов JPEG, PNG, GIF и BMP.
Есть четыре группы источников растровых изображений в Xamarin.Forms:
- Интернет (по указанному URL-адресу);
- изображения, внедренные как ресурсы в общей библиотеке;
- изображения, внедренные как ресурсы в проектах приложения платформы;
- любые источники, на которые может ссылаться объект
Stream
.NET, в том числеMemoryStream
.
Ресурсы растровых изображений в общей библиотеке не зависят от платформы, а аналогичные ресурсы в проектах платформы зависят от нее.
Примечание.
В тексте книги содержатся ссылки на переносимые библиотеки классов, замененные библиотеками .NET Standard. Все примеры кода в этой книге преобразованы для использования библиотек .NET Standard.
Растровое изображение задается путем установки для свойства Source
объекта Image
типа ImageSource
, абстрактного класса с тремя производными:
UriImageSource
— для доступа к растровому изображению через Интернет на основе объектаUri
, для которого установлено свойствоUri
;FileImageSource
— для доступа к растровому изображению, хранящемуся в проекте приложения платформы, на основе пути к папке и файлу, где для пути должно быть задано свойствоFile
;StreamImageSource
— для загрузки растрового изображения с помощью объектаStream
.NET, указанного путем возвращенияStream
отFunc
, для которого установлено свойствоStream
.
Кроме того, можно использовать следующие статические методы класса ImageSource
, каждый из которых возвращает объекты ImageSource
(распространенный способ):
ImageSource.FromUri
— для доступа к растровому изображению через Интернет на основе объектаUri
;ImageSource.FromResource
— для доступа к растровому изображению, хранимому в качестве внедренного ресурса в PCL приложения;ImageSource.FromResource
илиImageSource.FromResource
— для доступа к растровому изображению в другой исходной сборке;ImageSource.FromFile
— для доступа к растровому изображению из проекта приложения платформы;ImageSource.FromStream
— для загрузки растрового изображения на основе объектаStream
.
Класс, эквивалентный методам Image.FromResource
, отсутствует. Класс UriImageSource
полезен, если требуется управлять кэшированием. Класс FileImageSource
полезен в XAML. Класс StreamImageSource
полезен для асинхронной загрузки объектов Stream
, а ImageSource.FromStream
— для синхронной.
Растровые изображения, не зависящие от платформы
Проект WebBitmapCode загружает растровое изображение через Интернет с использованием ImageSource.FromUri
. Элементу Image
задается свойство Content
ContentPage
, поэтому он ограничен размером страницы. Независимо от размера растрового изображения ограниченный элемент Image
растягивается до размера своего контейнера, а растровое изображение отображается в своем максимальном размере в элементе Image
при сохранении пропорций изображения. Цвет областей Image
за пределами растрового изображения можно указать с помощью BackgroundColor
.
Пример WebBitmapXaml аналогичен описанному выше, в нем просто задается для свойства Source
URL-адрес. Преобразование выполняет класс ImageSourceConverter
.
Подбор размера и заливка
Вы можете управлять способом растягивания растрового изображения, задав для свойства Aspect
объекта Image
один из следующих членов перечисления Aspect
:
AspectFit
— учитывает пропорции (по умолчанию);Fill
— выполняет заливку области, пропорции не учитываются;AspectFill
— выполняет заливку области и учитывает пропорции, обрезает часть растрового изображения.
Внедренные ресурсы
Файл растрового изображения можно добавить в PCL или в папку в PCL. Укажите Build Action EmbeddedResource. В примере ResourceBitmapCode показано, как использовать ImageSource.FromResource
для загрузки файла. Имя ресурса, передаваемое в метод, состоит из имени сборки, за которым следует точка, дополнительное имя папки и точка, а затем имя файла.
Программа задает LayoutOptions.Center
для свойств VerticalOptions
и HorizontalOptions
объекта Image
, что делает элемент Image
неограниченным. Image
и растровое изображение имеют одинаковый размер:
- В iOS и Android
Image
представляет собой размер растрового изображения в пикселях. Растровые пиксели и пиксели экрана сопоставляются в соотношении "один к одному". - На универсальной платформе Windows
Image
— это размер растрового изображения в аппаратно-независимых единицах. На большинстве устройств каждый пиксель растрового изображения занимает несколько экранных пикселей.
В примере StackedBitmap Image
помещается в вертикальную ориентацию StackLayout
в XAML. Расширение разметки с именем ImageResourceExtension
помогает ссылаться на внедренный ресурс в XAML. Этот класс загружает ресурсы только из сборки, в которой он расположен, и поэтому не может быть помещен в библиотеку.
Дополнительные сведения об изменении размера
Желательно всегда согласованно изменять размер растровых изображений для всех платформ.
В эксперименте с примером StackedBitmap вы можете задать вертикальную ориентацию StackLayout
для WidthRequest
элемента Image
, чтобы обеспечить единообразие размеров на платформах, но с помощью этого способа можно только уменьшить размер.
Вы можете также задать HeightRequest
, чтобы обеспечить единообразие размеров изображения на платформах, но ограничение ширины растрового изображения сделает этот способ менее удобным. Для изображения в вертикальной ориентации StackLayout
HeightRequest
следует избегать.
Лучший подход — начать с растрового изображения, ширина которого больше ширины дисплея телефона в аппаратно-независимых единицах, и присвоить WidthRequest
желаемую ширину в этих единицах. Это показано в примере DeviceIndBitmapSize.
В примере MadTeaParty показана глава 7 книги "Алиса в стране чудес" Льюиса Кэролла с исходными иллюстрациями Джона Тенниела:
Просмотр и ожидание
В примере ImageBrowser пользователю позволяется просматривать стандартные изображения, хранящиеся на веб-сайте Xamarin. Для загрузки файла JSON со списком растровых изображений используется класс .NET WebRequest
.
Примечание.
Программы Xamarin.Forms для обращения к файлам через Интернет должны использовать HttpClient
, а не WebRequest
.
Программа использует ActivityIndicator
, чтобы определить, что происходят действия. При загрузке каждого растрового изображения свойство IsLoading
только для чтения для Image
имеет значение true
. Свойство IsLoading
поддерживается связываемым свойством, поэтому при его изменении происходит событие PropertyChanged
. Программа присоединяет обработчик к этому событию и использует текущее значение IsLoaded
, чтобы задать свойство IsRunning
для ActivityIndicator
.
Растровые изображения потоковой передачи
Метод ImageSource.FromStream
создает ImageSource
на основе Stream
.NET. Методу должен быть передан объект Func
, возвращающий объект Stream
.
Получение доступа к потокам
В примере BitmapStreams показано использование метода ImaageSource.FromStream
для загрузки растрового изображения, хранящегося в качестве внедренного ресурса, и загрузки растрового изображения через Интернет.
Создание растровых изображений во время выполнения
Все платформы Xamarin.Forms поддерживают формат файлов BMP без сжатия, который легко использовать в качестве конструкции в коде. Затем эти файлы хранятся в MemoryStream
. Этот подход позволяет алгоритмически создавать растровые изображения во время выполнения, как реализовано в классе BmpMaker
в библиотеке Xamrin.FormsBook Toolkit.
В примере самостоятельного выполнения DiyGradientBitmap показано использование BmpMaker
для создания растрового изображения с градиентом.
Растровые изображения для платформ
Все платформы Xamarin.Forms позволяют сохранять растровые изображения в сборках приложений платформы. Когда приложение Xamarin.Forms получает эти растровые изображения для платформ, они приобретают тип FileImageSource
. Эти растровые изображения используются для:
- свойства
Icon
дляMenuItem
. - свойства
Icon
дляToolbarItem
. - свойства
Image
дляButton
.
Сборки платформы уже содержат растровые изображения для значков и экранов-заставок:
- в проекте iOS в папке Resources;
- в проекте Android во вложенных папках в папке Resources;
- в проектах Windows в папке Assets (несмотря на то, что платформы Windows не ограничивают растровые изображения для этой папки).
В примере PlatformBitmaps используется код для отображения значка из проекта приложения платформы.
Разрешения для растровых изображений
Все платформы позволяют хранить несколько версий растровых изображений для разрешений различных устройств. Во время выполнения в зависимости от разрешения устройства на экране загружается правильная версия.
В iOS эти растровые изображения отличаются по суффиксу имени файла:
- нет суффикса для устройств со 160 точками на дюйм (1 пиксель на аппаратно-независимую единицу);
- Суффикс "@2x" для устройств с 320 DPI (2 пикселя в DIU)
- Суффикс "@3x" для устройств с 480 DPI (3 пикселя в DIU)
Растровое изображение, предназначенное для отображения в виде однодюймового квадрата, будет существовать в трех версиях:
- MyImage.jpg с квадратом 160 пикселей;
- MyImage@2x.jpg с квадратом 320 пикселей;
- MyImage@3x.jpg с квадратом 480 пикселей.
Программа будет ссылаться на это растровое изображение как на MyImage.jpg, но соответствующая версия будет получена во время выполнения в зависимости от разрешения экрана. При отсутствии ограничений растровое изображение всегда будет отображаться при 160 аппаратно-независимых единицах.
Для Android точечные рисунки хранятся в различных папках, вложенных вложенных в папку Resources:
- drawable-ldpi (низкое количество точек на дюйм) для устройств со 120 точками на дюйм (0,75 пикселя на аппаратно-независимую единицу);
- drawable-mdpi (среднее количество) для устройств со 160 точками на дюйм (1 пиксель на аппаратно-независимую единицу);
- drawable-hdpi (большое количество) для устройств с 240 точками на дюйм (1,5 пикселя на аппаратно-независимую единицу);
- drawable-xhdpi (очень большое количество) для устройств с 320 точками на дюйм (2 пикселя на аппаратно-независимую единицу);
- drawable-xxhdpi (сверхбольшое количество) для устройств с 480 точками на дюйм (3 пикселя на аппаратно-независимую единицу);
- drawable-xxxhdpi (супербольшое количество) для устройств с 640 точками на дюйм (4 пикселя на аппаратно-независимую единицу).
У растрового изображения, предназначенного для отображения в одном квадратном дюйме, у различных его версий будет одно и то же имя, но разный размер. Эти версии будут храниться в следующих папках:
- drawable-ldpi/MyImage.jpg с квадратом 120 пикселей;
- drawable-mdpi/MyImage.jpg с квадратом 160 пикселей;
- drawable-hdpi/MyImage.jpg с квадратом 240 пикселей;
- drawable-xhdpi/MyImage.jpg с квадратом 320 пикселей;
- drawable-xxhdpi/MyImage.jpg с квадратом 480 пикселей;
- drawable-xxxhdpi/MyImage.jpg с квадратом 640 пикселей.
Растровое изображение всегда будет отображаться при 160 аппаратно-независимых единицах. (Стандартный шаблон решения Xamarin.Forms содержит только папки hdpi, xhdpi и xxhdpi.)
Проект UWP поддерживает схему именования растровых изображений по коэффициенту масштабирования пикселей на аппаратно-независимую единицу (в процентах), например:
- MyImage.scale-200.jpg при квадрате 320 пикселей.
Допустимы только некоторые процентные значения. Среди примеров программ в этой книге только примеры с изображениями с суффиксами scale-200, но текущие шаблоны решений Xamarin.Forms также предусматривают scale-100, scale-125, scale-150 и scale-400.
При добавлении растровых изображений в проекты платформы у Build Action должно быть следующее значение:
- iOS: BundleResource
- Android: AndroidResource
- UWP: содержимое
В примере ImageTap создается два объекта, похожие на кнопки и состоящие из объектов Image
с установленным TapGestureRecognizer
. Предполагается, что объекты являются однодюймовыми квадратами. Свойство Source
для Image
задается с использованием объектов OnPlatform
и On
для ссылки на потенциально отличающиеся имена файлов на платформах. Растровые изображения содержат числа, указывающие размер пикселя, поэтому можно увидеть, растровое изображение какого размера получено и готовится для отображения.
Панели инструментов и их значки
Одним из основных мест использования растровых изображений, зависящих от платформы, является панель инструментов Xamarin.Forms, которая создается путем добавления объектов ToolbarItem
в коллекцию ToolbarItems
, определенную Page
. ToobarItem
происходит от MenuItem
, от которого она наследует некоторые свойства.
Среди всех свойств ToolbarItem
есть самые важные:
Text
— для текста, который может отображаться в зависимости от платформы иOrder
;Icon
типаFileImageSource
— для изображения, которое может отображаться в зависимости от платформы иOrder
;Order
типаToolbarItemOrder
— перечисление с тремя членами:Default
,Primary
иSecondary
.
Количество элементов Primary
должно быть ограничено тремя или четырьмя. Необходимо включить параметр Text
для всех элементов. Для большинства платформ только элементам Primary
требуется Icon
, но для Windows 8.1 требуется Icon
для всех элементов. У значков должен быть размер 32 аппаратно-независимые единицы. Тип FileImageSource
указывает, что они относятся к конкретной платформе.
ToolbarItem
запускает событие Clicked
при касании, подобно Button
. ToolbarItem
также поддерживает свойства Command
и CommandParameter
, часто используемые для MVVM. (См. статью Сводка главы 18. MVVM).
Для iOS и Android требуется, чтобы страница, на которой отображается панель инструментов, была NavigationPage
или страницей, к которой можно было бы перейти с помощью NavigationPage
. Программа ToolbarDemo устанавливает для свойства MainPage
класса App
конструктор NavigationPage
с аргументом ContentPage
, а также демонстрирует конструкцию и обработчик событий панели инструментов.
Изображения кнопок
Вы также можете использовать растровые изображения для определенной платформы, чтобы задать свойство Image
для Button
растрового изображения с квадратом размером 32 аппаратно-независимые единицы, как показано в примере ButtonImage.
Примечание.
Усовершенствовано использование изображений в кнопках. См. раздел Использование растровых изображений в кнопках.