Широкий цвет в Xamarin.iOS

В этой статье описывается широкий цвет и его использование в приложении Xamarin.iOS или Xamarin.Mac.

IOS 10 и macOS Sierra повышает поддержку форматов пикселей расширенного диапазона и цветовых пространств с широким диапазоном в системе, включая платформы, такие как core Graphics, Core Image, Metal и AVFoundation. Поддержка устройств с широкоцветными дисплеями упрощается, обеспечивая это поведение во всем графическом стеке.

Каталоги активов

Поддержка расширенных цветов с помощью каталогов активов

В iOS 10 и macOS Sierra Apple расширила каталоги активов, используемые для включения и классификации содержимого статического изображения в пакете приложения для поддержки широкого цвета.

Использование каталогов ресурсов предоставляет следующие преимущества для приложения:

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

Apple сделала следующие улучшения в каталогах активов для поддержки широкого цвета:

  • Они поддерживают 16-разрядное (на цветовый канал) исходное содержимое.
  • Они поддерживают каталогизацию содержимого путем отображения гамма. Содержимое можно пометить как для SRGB, так и для отображения gamuts P3.

Разработчик имеет три варианта поддержки широкого цветового содержимого в своих приложениях:

  1. Не делать ничего . Так как содержимое с широким цветом должно использоваться только в ситуациях, когда приложение должно отображать яркие цвета (где они будут улучшать взаимодействие пользователя), содержимое вне этого требования должно оставаться как есть. Он будет отображаться правильно во всех аппаратных ситуациях.
  2. Обновление существующего содержимого до отображения P3 . Это требует от разработчика заменить существующее содержимое изображения в каталоге активов новым обновленным файлом в формате P3 и пометить его таким образом в редакторе активов. Во время сборки производный образ SRGB будет создан из этих ресурсов.
  3. Предоставление оптимизированного содержимого ресурса . В этой ситуации разработчик предоставит как 8-разрядное представление SRGB, так и 16-разрядное представление отображения P3 каждого изображения в каталоге активов (правильно помеченное в редакторе активов).

Развертывание каталога активов

Следующее происходит, когда разработчик отправляет приложение в App Store с каталогами активов, включающих содержимое изображения с широким цветом:

  • При развертывании приложения для конечного пользователя приложение Slicing гарантирует, что на устройство пользователя будет доставлен только соответствующий вариант содержимого.
  • На устройстве, не поддерживающем широкий цвет, нет полезных данных для включения содержимого с широким цветом, так как он никогда не поставляется на устройство.
  • NSImage в macOS Sierra (и более поздних версиях) автоматически выбирает лучшее представление содержимого для дисплея оборудования.
  • Отображаемое содержимое будет обновляться автоматически при изменении характеристик оборудования устройства.

Служба хранилища каталога активов

Хранилище каталога активов имеет следующие свойства и последствия для приложения:

  • Во время сборки Apple пытается оптимизировать хранение содержимого изображения с помощью высококачественных преобразований изображений.
  • 16-разрядные каналы используются для широкого цветового содержимого.
  • Сжатие зависимых от содержимого изображений используется для снижения размеров содержимого. Добавлены новые "потери" сжатия для дальнейшего оптимизации размеров контента.

Отрисовка внеэкранных изображений в приложении

В зависимости от типа создаваемого приложения пользователь может включить содержимое изображения, которое они собрали из Интернета или создать содержимое изображения непосредственно внутри приложения (например, векторное приложение для рисования).

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

Цвет рисования в iOS

Прежде чем обсуждать, как правильно нарисовать широкоцветное изображение в iOS 10, ознакомьтесь со следующим общим кодом рисования iOS:

public UIImage DrawWideColorImage ()
{
    var size = new CGSize (250, 250);
    UIGraphics.BeginImageContext (size);

    ...

    UIGraphics.EndImageContext ();
    return image = UIGraphics.GetImageFromCurrentImageContext ();
    }

Существуют проблемы со стандартным кодом, который необходимо решить , прежде чем его можно будет использовать для рисования широкого цвета изображения. Метод UIGraphics.BeginImageContext (size) , используемый для запуска рисования изображений iOS, имеет следующие ограничения:

  • Не удается создать контексты изображения с более чем 8 битами на канал цветов.
  • Он не может представлять цвета в цветовом пространстве расширенного диапазона SRGB.
  • Он не имеет возможности предоставлять интерфейс для создания контекстов в цветовом пространстве, отличном от SRGB, из-за низкоуровневых подпрограмм C, вызываемых в фоновом режиме.

Для обработки этих ограничений и рисования широкоцветного изображения в iOS 10 используйте следующий код:

public UIImage DrawWideColorImage ()
{
    var size = new CGSize (250, 250);
    var render = new UIGraphicsImageRenderer (size);

    var image = render.CreateImage ((UIGraphicsImageRendererContext context) => {
        var bounds = context.Format.Bounds;
        CGRect slice;
        CGRect remainder;
        bounds.Divide (bounds.Width / 2, CGRectEdge.MinXEdge, out slice, out remainder);

        var redP3 = UIColor.FromDisplayP3 (1.0F, 0.0F, 0.0F, 1.0F);
        redP3.SetColor ();
        context.FillRect (slice);

        var redRGB = UIColor.Red;
        redRGB.SetColor ();
        context.FillRect (remainder);
    });

    // Return results
    return image;
}

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

  • По умолчанию он полностью управляется цветом.
  • Он поддерживает цветовое пространство расширенного диапазона SRGB по умолчанию.
  • Он интеллектуально решает, должен ли он отображаться в SRGB или расширенном диапазоне цветового пространства SRGB на основе возможностей устройства iOS, на котором работает приложение.
  • Он полностью и автоматически управляет контекстом изображения (CGContext) время существования, поэтому разработчику не нужно беспокоиться о вызове команд начала и завершения контекста.
  • Он совместим с методом UIGraphics.GetCurrentContext() .

Метод CreateImageUIGraphicsImageRenderer класса вызывается для создания широкоцветного изображения и передает обработчик завершения с контекстом изображения для рисования. Весь рисунок выполняется внутри этого обработчика завершения следующим образом:

  • Метод UIColor.FromDisplayP3 создает полностью насыщенный красный цвет в широкой цветовой гамме отображения P3 и используется для рисования первой половины прямоугольника.
  • Вторая половина прямоугольника рисуется в обычном sRGB полностью насыщенный красный цвет для сравнения.

Цвет рисования в macOS

Класс NSImage был расширен в macOS Sierra для поддержки рисования изображений wide Color. Например:

var size = CGSize(250,250);
var wideColorImage = new NSImage(size, false, (drawRect) =>{
    var rects = drawRect.Divide(drawRect.Size.Width/2,CGRect.MinXEdge);

    var color = new NSColor(1.0, 0.0, 0.0, 1.0).Set();
    var path = new NSBezierPath(rects.Slice).Fill();

    color = new NSColor(1.0, 0.0, 0.0, 1.0).Set();
    path = new NSBezierPath(rects.Remainder).Fill();

    // Return modified
    return true;
});

Отрисовка изображений на экране в приложении

Чтобы отобразить широкоцветные изображения на экране, процесс работает так же, как и рисование изображения цвета вне экрана для macOS и iOS, представленных выше.

Отрисовка на экране в iOS

Когда приложению нужно отобразить изображение в широком цвете на экране в iOS, переопределите Draw метод UIView вопроса как обычно. Например:

using System;
using UIKit;
using CoreGraphics;

namespace MonkeyTalk
{
    public class MonkeyView : UIView
    {
        public MonkeyView ()
        {
        }

        public override void Draw (CGRect rect)
        {
            base.Draw (rect);

            // Draw the image to screen
        ...
        }
    }
}

Так как iOS 10 делает с классом UIGraphicsImageRenderer , показанным выше, он интеллектуально решает, должен ли он отображаться в SRGB или расширенном диапазоне sRGB Цветовое пространство на основе возможностей устройства iOS, на котором работает приложение при вызове Draw метода. Кроме того, он UIImageView был управляемым цветом с iOS 9.3, а также.

Если приложению необходимо знать, как выполняется отрисовка на объекте UIView или UIViewControllerможет проверка новое DisplayGamut свойство UITraitCollection класса. Это значение будет перечислением UIDisplayGamut из следующих значений:

  • P3
  • Srgb
  • Не определено

Если приложение хочет контролировать, какое цветовое пространство используется для рисования изображения, оно может использовать новое ContentsFormat свойство для указания требуемого CALayer цветового пространства. Это значение может быть перечислением CAContentsFormat следующих значений:

  • Gray8Uint
  • Rgba16Float
  • Rgba8Uint

Отрисовка на экране в macOS

Когда приложению необходимо отобразить изображение в широком цвете на экране в macOS, переопределите DrawRect метод NSView вопроса как обычно. Например:

using System;
using AppKit;
using CoreGraphics;
using CoreAnimation;

namespace MonkeyTalkMac
{
    public class MonkeyView : NSView
    {
        public MonkeyView ()
        {
        }

        public override void DrawRect (CGRect dirtyRect)
        {
            base.DrawRect (dirtyRect);

            // Draw graphics into the view
            ...
        }
    }
}

Опять же, он интеллектуально решает, должен ли он отображаться в sRGB или расширенном диапазоне sRGB цветового пространства на основе возможностей оборудования Mac, на котором работает приложение при вызове DrawRect метода.

Если приложение хочет контролировать, какое цветовое пространство используется для рисования изображения, оно может использовать новое DepthLimit свойство класса для указания требуемого NSWindow цветового пространства. Это значение может быть перечислением NSWindowDepth следующих значений:

  • OneHundredTwentyEightBitRgb
  • 6fourBitRgb
  • TwentyfourBitRgb