Szeroki kolor na platformie Xamarin.iOS

W tym artykule opisano szeroki kolor i sposób jej użycia w aplikacji platformy Xamarin.iOS lub Xamarin.Mac.

System iOS 10 i macOS Sierra rozszerza obsługę formatów pikseli rozszerzonego zakresu i przestrzeni kolorów szerokiej gamy w całym systemie, w tym struktur, takich jak Core Graphics, Core Image, Metal i AVFoundation. Obsługa urządzeń z wyświetlaczami o szerokim kolorze jest jeszcze bardziej złagodowana przez zapewnienie tego zachowania w całym stosie graficznym.

Wykazy zasobów

Obsługa szerokiego koloru za pomocą katalogów zasobów

W systemach iOS 10 i macOS Sierra firma Apple rozszerzyła katalogi zasobów używane do dołączania i kategoryzowania zawartości obrazów statycznych w pakiecie aplikacji w celu obsługi szerokiego koloru.

Korzystanie z wykazów zasobów zapewnia następujące korzyści dla aplikacji:

  • Zapewniają one najlepszą opcję wdrożenia dla zasobów obrazów statycznych.
  • Obsługują automatyczną korektę kolorów.
  • Obsługują one automatyczną optymalizację formatu pikseli.
  • Obsługują one fragmentowanie aplikacji i cieniowanie aplikacji, co gwarantuje, że tylko odpowiednia zawartość zostanie dostarczona do urządzenia użytkownika końcowego.

Firma Apple wprowadziła następujące ulepszenia w katalogach zasobów w celu obsługi szerokiego koloru:

  • Obsługują 16-bitową (na kanał kolorów) zawartość źródłową.
  • Obsługują one katalogowanie zawartości według gamy wyświetlania. Zawartość może być oznaczona jako sRGB lub Wyświetl gamę P3.

Deweloper ma trzy opcje obsługi szerokiej zawartości kolorów w swoich aplikacjach:

  1. Nie rób nic — ponieważ zawartość w szerokim kolorze powinna być używana tylko w sytuacjach, w których aplikacja musi wyświetlać żywe kolory (gdzie poprawią środowisko użytkownika), zawartość poza tym wymaganiem powinna być pozostawiona zgodnie z oczekiwaniami. Będzie on nadal poprawnie renderowany we wszystkich sytuacjach sprzętowych.
  2. Uaktualnij istniejącą zawartość do wyświetlania P3 — wymaga to od dewelopera zastąpienia istniejącej zawartości obrazu w katalogu zasobów nowym uaktualnionym plikiem w formacie P3 i otagowaniu go jako takiego w Edytorze zasobów. W czasie kompilacji na podstawie tych zasobów zostanie wygenerowany obraz pochodny sRGB.
  3. Zapewnij zoptymalizowaną zawartość zasobów — w tej sytuacji deweloper udostępni 8-bitowy sRGB i 16-bitową wizję P3 każdego obrazu w katalogu zasobów (odpowiednio oznakowany w edytorze zasobów).

Wdrażanie wykazu zasobów

Podczas przesyłania aplikacji do sklepu App Store z wykazami zasobów, które zawierają szeroką zawartość obrazu koloru, wystąpią następujące elementy:

  • Gdy aplikacja zostanie wdrożona dla użytkownika końcowego, fragmentowanie aplikacji zapewni, że na urządzeniu użytkownika zostanie dostarczony tylko odpowiedni wariant zawartości.
  • Na urządzeniu, które nie obsługuje szerokiego koloru, nie ma kosztów ładunku dla wprowadzania zawartości w szerokim kolorze, ponieważ nigdy nie jest dostarczany do urządzenia.
  • NSImage w systemie macOS Sierra (i nowszym) automatycznie wybierze najlepszą reprezentację zawartości dla wyświetlacza sprzętu.
  • Wyświetlana zawartość zostanie odświeżona automatycznie, gdy lub jeśli parametry wyświetlania sprzętu urządzenia się zmienią.

Magazyn wykazu zasobów

Magazyn wykazu zasobów ma następujące właściwości i implikacje dla aplikacji:

  • W czasie kompilacji firma Apple próbuje zoptymalizować magazyn zawartości obrazu za pomocą konwersji obrazów o wysokiej jakości.
  • 16-bitowe są używane dla kanału kolorów dla szerokiej zawartości kolorów.
  • Kompresja obrazu zależnego od zawartości jest używana do obniżenia rozmiaru zawartości dostarczanej. Dodano nowe kompresje "stratowe", aby jeszcze bardziej zoptymalizować rozmiary zawartości.

Renderowanie obrazów poza ekranem w aplikacji

Na podstawie typu tworzonej aplikacji może ona umożliwić użytkownikowi dołączenie zawartości obrazu zebranej z Internetu lub utworzenie zawartości obrazu bezpośrednio wewnątrz aplikacji (na przykład aplikacji rysunku wektorowego).

W obu tych przypadkach aplikacja może renderować wymagane obrazy poza ekranem w szerokim kolorze przy użyciu rozszerzonych funkcji dodanych zarówno do systemów iOS, jak i macOS.

Rysowanie szerokiego koloru w systemie iOS

Przed rozpoczęciem dyskusji na temat poprawnego rysowania obrazu szerokiego koloru w systemie iOS 10 zapoznaj się z następującym typowym kodem rysunkowym dla systemu iOS:

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

    ...

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

Występują problemy ze standardowym kodem, który należy rozwiązać , zanim będzie można go użyć do narysowania obrazu w szerokim kolorze. Metoda używana do uruchamiania UIGraphics.BeginImageContext (size) rysunku obrazu systemu iOS ma następujące ograniczenia:

  • Nie może tworzyć kontekstów obrazu z więcej niż 8 bitami na kanał kolorów.
  • Nie może reprezentować kolorów w przestrzeni kolorów rozszerzonego zakresu sRGB.
  • Nie ma możliwości zapewnienia interfejsu do tworzenia kontekstów w przestrzeni kolorów innej niż sRGB ze względu na procedury niskiego poziomu C wywoływane w tle.

Aby obsłużyć te ograniczenia i narysować szeroki obraz w systemie iOS 10, użyj następującego kodu:

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

Nowa UIGraphicsImageRenderer klasa tworzy nowy kontekst obrazu, który może obsługiwać przestrzeń kolorów rozszerzonego zakresu sRGB i ma następujące funkcje:

  • Jest on domyślnie w pełni zarządzany kolorem.
  • Obsługuje domyślnie przestrzeń kolorów rozszerzonego zakresu sRGB.
  • Inteligentnie decyduje, czy ma być renderowany w przestrzeni kolorów sRGB lub Extended Range sRGB na podstawie możliwości urządzenia z systemem iOS, na którym działa aplikacja.
  • W pełni zarządza kontekstem obrazu (CGContext), aby deweloper nie musiał martwić się o wywołanie poleceń początkowych i końcowych kontekstu.
  • Jest ona zgodna UIGraphics.GetCurrentContext() z metodą .

Metoda CreateImageUIGraphicsImageRenderer klasy jest wywoływana w celu utworzenia obrazu w szerokim kolorze i przekazania procedury obsługi ukończenia z kontekstem obrazu w celu narysowania. Cały rysunek jest wykonywany wewnątrz tego programu obsługi uzupełniania w następujący sposób:

  • Metoda UIColor.FromDisplayP3 tworzy nowy w pełni nasycony czerwony kolor w szerokiej gamie Display P3 Color Space i służy do rysowania pierwszej połowy prostokąta.
  • Druga połowa prostokąta jest rysowana w normalnym kolorze sRGB w pełni nasyconym czerwonym kolorem do porównania.

Rysowanie szerokiego koloru w systemie macOS

Klasa NSImage została rozszerzona w systemie macOS Sierra, aby obsługiwać rysunek obrazów Wide Color. Na przykład:

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

Renderowanie obrazów na ekranie w aplikacji

Aby renderować obrazy szerokiego koloru na ekranie, proces działa podobnie do rysowania obrazu koloru szerokiego poza ekranem dla systemów macOS i iOS przedstawionych powyżej.

Renderowanie na ekranie w systemie iOS

Gdy aplikacja musi renderować obraz w szerokim kolorze na ekranie w systemie iOS, przesłoń Draw metodę UIView danego obiektu w zwykły sposób. Na przykład:

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
        ...
        }
    }
}

Ponieważ system iOS 10 korzysta z przedstawionej UIGraphicsImageRenderer powyżej klasy, inteligentnie decyduje, czy ma być renderowany w przestrzeni kolorów sRGB lub Rozszerzonego zakresu sRGB w oparciu o możliwości urządzenia z systemem iOS, na którym działa aplikacja po wywołaniu Draw metody. UIImageView Ponadto kolor jest zarządzany od systemu iOS 9.3, jak również.

Jeśli aplikacja musi wiedzieć, jak renderowanie jest wykonywane na obiekcie UIView lub UIViewController, może sprawdzić nową DisplayGamut właściwość UITraitCollection klasy. Ta wartość będzie wyliczeniową UIDisplayGamut następujących wartości:

  • P3
  • Srgb
  • Nieokreślony

Jeśli aplikacja chce kontrolować, która przestrzeń kolorów jest używana do narysowania obrazu, może użyć nowej ContentsFormat właściwości CALayer elementu , aby określić żądaną przestrzeń kolorów. Ta wartość może być wyliczeniem CAContentsFormat następujących elementów:

  • Gray8Uint
  • Rgba16Float
  • Rgba8Uint

Renderowanie na ekranie w systemie macOS

Gdy aplikacja musi renderować obraz w szerokim kolorze na ekranie w systemie macOS, przesłoń DrawRect metodę NSView danego obiektu w zwykły sposób. Na przykład:

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
            ...
        }
    }
}

Ponownie inteligentnie decyduje, czy ma być renderowany w przestrzeni kolorów sRGB lub Extended Range sRGB na podstawie możliwości sprzętu mac, na którym działa aplikacja, gdy DrawRect jest wywoływana metoda.

Jeśli aplikacja chce kontrolować, która przestrzeń kolorów jest używana do narysowania obrazu, może użyć nowej DepthLimit właściwości NSWindow klasy, aby określić żądaną przestrzeń kolorów. Ta wartość może być wyliczeniem NSWindowDepth następujących elementów:

  • OneHundredTwentyEightBitRgb
  • SixtyfourBitRgb
  • TwentyfourBitRgb