Breite Farbe in Xamarin.iOS

In diesem Artikel werden breite Farben behandelt und erläutert, wie sie in einer Xamarin.iOS- oder Xamarin.Mac-App verwendet werden kann.

iOS 10 und macOS Sierra verbessern die Unterstützung für Pixelformate mit erweitertem Bereich und farbliche Bereiche im gesamten System, einschließlich Frameworks wie Core Graphics, Core Image, Metal und AVFoundation. Die Unterstützung für Geräte mit breitfarbigen Displays wird weiter vereinfacht, indem dieses Verhalten im gesamten Grafikstapel bereitgestellt wird.

Asset-Kataloge

Unterstützung von "Breite Farbe" mit Ressourcenkatalogen

In iOS 10 und macOS Sierra hat Apple die Ressourcenkataloge erweitert, die verwendet werden, um statische Bildinhalte im Paket der App einzuschließen und zu kategorisieren, um breite Farben zu unterstützen.

Die Verwendung von Objektkatalogen bietet für eine App die folgenden Vorteile:

  • Sie bieten die beste Bereitstellungsoption für statische Imageressourcen.
  • Sie unterstützen die automatische Farbkorrektur.
  • Sie unterstützen die automatische Pixelformatoptimierung.
  • Sie unterstützen App Slicing und App Thinning, wodurch sichergestellt wird, dass nur die relevanten Inhalte an das Gerät des Endbenutzers übermittelt werden.

Apple hat die folgenden Verbesserungen an Asset Catalogs für breite Farbunterstützung vorgenommen:

  • Sie unterstützen 16-Bit-Quellinhalte (pro Farbkanal).
  • Sie unterstützen die Katalogisierung von Inhalten durch Anzeigeumfang. Inhalte können entweder für den sRGB- oder P3-Anzeigeumfang markiert werden.

Der Entwickler verfügt über drei Optionen zur Unterstützung von Breitfarbinhalten in seinen Apps:

  1. Nichts tun : Da Inhalte mit breiter Farbe nur in Situationen verwendet werden sollten, in denen die App lebendige Farben anzeigen muss (wo sie die Benutzerfreundlichkeit verbessern), sollten Inhalte außerhalb dieser Anforderung unverändert bleiben. Es wird weiterhin ordnungsgemäß in allen Hardwaresituationen gerendert.
  2. Upgrade vorhandener Inhalte auf Anzeige P3 : Dazu muss der Entwickler den vorhandenen Bildinhalt in ihrem Objektkatalog durch eine neue, aktualisierte Datei im P3-Format ersetzen und im Asset-Editor als solche taggen. Zur Erstellungszeit wird aus diesen Assets ein sRGB-Derivatimage generiert.
  3. Bereitstellen optimierter Ressourceninhalte : In dieser Situation stellt der Entwickler sowohl eine 8-Bit-sRGB- als auch eine 16-Bit-Anzeige P3-Vision für jedes Bild im Assetkatalog bereit (ordnungsgemäß im Asset-Editor markiert).

Bereitstellung des Ressourcenkatalogs

Folgendes tritt auf, wenn der Entwickler eine App an die App Store mit Objektkatalogen übermittelt, die Bildinhalte mit breitem Farbton enthalten:

  • Wenn die App für den Endbenutzer bereitgestellt wird, stellt App Slicing sicher, dass nur die entsprechende Inhaltsvariante an das Gerät des Benutzers übermittelt wird.
  • Auf Geräten, die keine breite Farbe unterstützen, fallen keine Nutzlastkosten für das Einschließen von Inhalten mit breitem Farbton an, da sie nie an das Gerät geliefert werden.
  • NSImage unter macOS Sierra (und höher) wird automatisch die beste Inhaltsdarstellung für die Anzeige der Hardware ausgewählt.
  • Der angezeigte Inhalt wird automatisch aktualisiert, wenn oder wenn sich die Eigenschaften der Gerätehardware ändern.

Speicher des Ressourcenkatalogs

Der Ressourcenkatalogspeicher hat die folgenden Eigenschaften und Auswirkungen auf eine App:

  • Zur Buildzeit versucht Apple, die Speicherung des Bildinhalts durch hochwertige Bildkonvertierungen zu optimieren.
  • 16-Bits werden pro Farbkanal für breite Farbinhalte verwendet.
  • Die inhaltsabhängige Bildkomprimierung wird verwendet, um die Zustellgröße von Inhalten zu verringern. Neue "verlustbehaftete" Komprimierungen wurden hinzugefügt, um die Inhaltsgrößen weiter zu optimieren.

Rendern von Off-Screen Bildern in der App

Basierend auf dem Typ der erstellten App kann es dem Benutzer ermöglichen, Bildinhalte einzuschließen, die er aus dem Internet gesammelt hat, oder Bildinhalte direkt in der App zu erstellen (z. B. eine Vektorzeichnungs-App).

In beiden Fällen kann die App die erforderlichen Bilder mit erweiterten Features, die sowohl iOS als auch macOS hinzugefügt wurden, von der Bildschirmseite in breitem Farbton rendern.

Zeichnen von Breite Farbe in iOS

Bevor Sie darüber diskutieren, wie Sie ein Bild mit breiter Farbe in iOS 10 richtig zeichnen, sehen Sie sich den folgenden allgemeinen iOS-Zeichnungscode an:

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

    ...

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

Es gibt Probleme mit dem Standardcode, die behoben werden müssen, bevor er zum Zeichnen eines Breitfarbbilds verwendet werden kann. Die UIGraphics.BeginImageContext (size) Zum Starten der iOS-Bildzeichnung verwendete Methode weist die folgenden Einschränkungen auf:

  • Es können keine Bildkontexte mit mehr als 8 Bits pro Farbkanal erstellt werden.
  • Farben im erweiterten Bereich sRGB-Farbraum können nicht dargestellt werden.
  • Es ist nicht in der Lage, eine Schnittstelle zum Erstellen von Kontexten in einem Nicht-sRGB-Farbraum bereitzustellen, da die C-Routinen auf niedriger Ebene im Hintergrund aufgerufen werden.

Verwenden Sie stattdessen den folgenden Code, um diese Einschränkungen zu behandeln und ein Bild mit breiter Farbe in iOS 10 zu zeichnen:

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

Die neue UIGraphicsImageRenderer Klasse erstellt einen neuen Bildkontext, der den erweiterten sRGB-Farbraum verarbeiten kann, und verfügt über die folgenden Features:

  • Es wird standardmäßig vollständig farbverwaltet.
  • Es unterstützt standardmäßig den Erweiterten Bereich sRGB-Farbraum.
  • Es entscheidet intelligent, ob es im sRGB- oder Erweiterten sRGB-Farbraum gerendert werden soll, basierend auf den Funktionen des iOS-Geräts, auf dem die App ausgeführt wird.
  • Es verwaltet die Lebensdauer des Bildkontexts (CGContext) vollständig und automatisch, sodass sich der Entwickler keine Gedanken über das Aufrufen von Start- und Endkontextbefehlen machen muss.
  • Es ist mit der UIGraphics.GetCurrentContext() -Methode kompatibel.

Die CreateImage -Methode der UIGraphicsImageRenderer -Klasse wird aufgerufen, um ein Breitfarbbild zu erstellen, und hat einen Vervollständigungshandler mit dem Bildkontext übergeben, in den er zeichnen kann. Die gesamte Zeichnung erfolgt in diesem Vervollständigungshandler wie folgt:

  • Die UIColor.FromDisplayP3 Methode erstellt eine neue vollgesättigte rote Farbe im breiten Farbraum anzeige P3 Farbraum und wird verwendet, um die erste Hälfte des Rechtecks zu zeichnen.
  • Die zweite Hälfte des Rechtecks wird für den Vergleich in der normalen sRGB vollgesättigten roten Farbe gezeichnet.

Zeichnen von "Breite Farbe" in macOS

Die NSImage Klasse wurde in macOS Sierra erweitert, um das Zeichnen von Breitfarbbildern zu unterstützen. Beispiel:

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

Rendern von Bildschirmbildern in der App

Zum Rendern von Breitfarbbildern auf dem Bildschirm funktioniert der Prozess ähnlich wie das Zeichnen eines off-Screen-Bilds mit breiter Farbe für macOS und iOS, das oben dargestellt wurde.

Rendern auf dem Bildschirm in iOS

Wenn die App ein Bild in breitem Farbton auf dem Bildschirm in iOS rendern muss, überschreiben Sie die Draw Methode der UIView betreffenden wie gewohnt. Beispiel:

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

Wie iOS 10 mit der UIGraphicsImageRenderer oben gezeigten Klasse, entscheidet es intelligent, ob es im sRGB- oder Erweiterten Bereich sRGB-Farbraum gerendert werden soll, basierend auf den Funktionen des iOS-Geräts, auf dem die App ausgeführt wird, wenn die Draw Methode aufgerufen wird. Darüber hinaus wurde die UIImageView Farbe seit iOS 9.3 ebenfalls verwaltet.

Wenn die App wissen muss, wie das Rendern für ein UIView oder UIViewControllererfolgt, kann sie die neue DisplayGamut Eigenschaft der UITraitCollection -Klasse überprüfen. Bei diesem Wert handelt es sich um eine UIDisplayGamut Aufzählung der folgenden Werte:

  • P3
  • Srgb
  • Nicht angegeben.

Wenn die App steuern möchte, welcher Farbraum zum Zeichnen eines Bilds verwendet wird, kann sie eine neue ContentsFormat Eigenschaft von CALayer verwenden, um den gewünschten Farbraum anzugeben. Bei diesem Wert kann es sich um eine CAContentsFormat Aufzählung der folgenden Werte handelt:

  • Gray8Uint
  • Rgba16Float
  • Rgba8Uint

Rendern auf dem Bildschirm in macOS

Wenn die App ein Bild in breitem Farbton auf dem Bildschirm in macOS rendern muss, überschreiben Sie die DrawRect Methode der NSView betreffenden wie gewohnt. Beispiel:

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

Auch hier entscheidet es intelligent, ob es im sRGB- oder Erweiterten Bereichs-sRGB-Farbraum gerendert werden soll, basierend auf den Funktionen der Mac-Hardware, auf der die App ausgeführt wird, wenn die DrawRect Methode aufgerufen wird.

Wenn die App steuern möchte, welcher Farbraum zum Zeichnen eines Bilds verwendet wird, kann sie eine neue DepthLimit Eigenschaft der NSWindow -Klasse verwenden, um den gewünschten Farbraum anzugeben. Bei diesem Wert kann es sich um eine NSWindowDepth Aufzählung der folgenden Werte handelt:

  • OneHundredTwentyEightBitRgb
  • SixtyfourBitRgb
  • TwentyfourBitRgb