Поделиться через


Аннотация к главе 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. Эти растровые изображения используются для:

Сборки платформы уже содержат растровые изображения для значков и экранов-заставок:

  • в проекте 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.

Примечание.

Усовершенствовано использование изображений в кнопках. См. раздел Использование растровых изображений в кнопках.