Share via


Colore wide in Xamarin.iOS

Questo articolo illustra il colore esteso e come può essere usato in un'app Xamarin.iOS o Xamarin.Mac.

iOS 10 e macOS Sierra migliorano il supporto per i formati di pixel di intervallo esteso e gli spazi di colori a gamma estesa in tutto il sistema, inclusi framework come Core Graphics, Core Image, Metal e AVFoundation. Il supporto per i dispositivi con schermi a colori wide è ulteriormente facilitato fornendo questo comportamento nell'intero stack di grafica.

Cataloghi asset

Supporto di un colore wide con cataloghi di asset

In iOS 10 e macOS Sierra, Apple ha espanso i cataloghi di asset usati per includere e classificare il contenuto delle immagini statiche nel bundle dell'app per supportare un colore ampio.

L'uso dei cataloghi di asset offre i vantaggi seguenti a un'app:

  • Offrono l'opzione di distribuzione migliore per gli asset di immagine statici.
  • Supportano la correzione automatica dei colori.
  • Supportano l'ottimizzazione automatica del formato pixel.
  • Supportano slicing delle app e thinning delle app, assicurando che solo il contenuto pertinente venga recapitato al dispositivo dell'utente finale.

Apple ha apportato i miglioramenti seguenti ai cataloghi di asset per il supporto di colori wide:

  • Supportano il contenuto di origine a 16 bit (per canale colore).
  • Supportano la catalogazione del contenuto in base alla gamma di visualizzazione. Il contenuto può essere contrassegnato per la gamma sRGB o Display P3.

Lo sviluppatore ha tre opzioni per supportare il contenuto a colori wide nelle app:

  1. Non eseguire alcuna operazione: poiché il contenuto a colori wide deve essere usato solo in situazioni in cui l'app deve visualizzare colori vividi (dove miglioreranno l'esperienza dell'utente), il contenuto al di fuori di questo requisito deve essere lasciato così come è. Il rendering continuerà a essere eseguito correttamente in tutte le situazioni hardware.
  2. Aggiornare il contenuto esistente alla visualizzazione P3 : questo richiede allo sviluppatore di sostituire il contenuto dell'immagine esistente nel catalogo asset con un nuovo file aggiornato nel formato P3 e contrassegnarlo come tale nell'Editor asset. In fase di compilazione, verrà generata un'immagine derivata sRGB da questi asset.
  3. Fornire contenuto di asset ottimizzati: in questa situazione, lo sviluppatore fornirà sia una visione P3 a 8 bit che una visione P3 di visualizzazione A 16 bit di ogni immagine nel Catalogo asset (contrassegnata correttamente nell'editor di asset).

Distribuzione del catalogo di asset

Quando lo sviluppatore invia un'app all'App Store con cataloghi di asset che includono contenuto di immagini a colori wide, si verificherà quanto segue:

  • Quando l'app viene distribuita all'utente finale, il sezionamento delle app garantisce che solo la variante di contenuto appropriata venga recapitata al dispositivo dell'utente.
  • Nel dispositivo che non supportano il colore wide non è previsto alcun costo di payload per l'inclusione di contenuto a colori wide, in quanto non viene mai spedito al dispositivo.
  • NSImage in macOS Sierra (e versioni successive) selezionerà automaticamente la rappresentazione del contenuto migliore per la visualizzazione dell'hardware.
  • Il contenuto visualizzato verrà aggiornato automaticamente quando o se le caratteristiche di visualizzazione dell'hardware dei dispositivi cambiano.

Archiviazione di Catalogo asset

L'archiviazione di Asset Catalog presenta le proprietà e le implicazioni seguenti per un'app:

  • In fase di compilazione, Apple tenta di ottimizzare l'archiviazione del contenuto dell'immagine tramite conversioni di immagini di alta qualità.
  • I 16 bit vengono usati per canale colore per il contenuto a colori wide.
  • La compressione delle immagini dipendenti dal contenuto viene usata per ridurre le dimensioni dei contenuti finali. Sono state aggiunte nuove compressioni "lossy" per ottimizzare ulteriormente le dimensioni del contenuto.

Rendering di immagini fuori schermo nell'app

In base al tipo di app in fase di creazione, potrebbe consentire all'utente di includere il contenuto dell'immagine che ha raccolto da Internet o creare contenuti di immagini direttamente all'interno dell'app ( ad esempio un'app di disegno vettoriale).

In entrambi questi casi, l'app può eseguire il rendering delle immagini richieste fuori schermo in un colore wide usando funzionalità avanzate aggiunte sia a iOS che a macOS.

Disegno di un colore largo in iOS

Prima di discutere come disegnare correttamente un'immagine a colori wide in iOS 10, esaminare il codice di disegno iOS comune seguente:

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

    ...

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

Esistono problemi con il codice standard che dovrà essere risolto prima che possa essere usato per disegnare un'immagine a colori wide. Il UIGraphics.BeginImageContext (size) metodo usato per avviare il disegno di immagini iOS presenta le limitazioni seguenti:

  • Non può creare contesti di immagine con più di 8 bit per canale di colore.
  • Non può rappresentare i colori nello spazio dei colori sRGB dell'intervallo esteso.
  • Non ha la possibilità di fornire un'interfaccia per creare contesti in uno spazio colore non sRGB a causa delle routine C di basso livello chiamate in background.

Per gestire queste limitazioni e disegnare un'immagine a colori wide in iOS 10, usare invece il codice seguente:

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

La nuova UIGraphicsImageRenderer classe crea un nuovo contesto di immagine in grado di gestire lo spazio colore sRGB dell'intervallo esteso e dispone delle funzionalità seguenti:

  • Il colore è completamente gestito per impostazione predefinita.
  • Supporta lo spazio colore sRGB dell'intervallo esteso per impostazione predefinita.
  • Decide in modo intelligente se deve eseguire il rendering nello spazio colore sRGB o nello spazio dei colori sRGB dell'intervallo esteso in base alle funzionalità del dispositivo iOS in cui è in esecuzione l'app.
  • Gestisce completamente e automaticamente la durata del contesto dell'immagine (CGContext) in modo che lo sviluppatore non si preoccupi di chiamare i comandi di inizio e di fine contesto.
  • È compatibile con il UIGraphics.GetCurrentContext() metodo .

Il CreateImage metodo della UIGraphicsImageRenderer classe viene chiamato per creare un'immagine a colori wide e passare un gestore di completamento con il contesto dell'immagine in cui disegnare. Tutto il disegno viene eseguito all'interno di questo gestore di completamento come indicato di seguito:

  • Il UIColor.FromDisplayP3 metodo crea un nuovo colore rosso completamente saturo nella vasta gamma Display P3 Color Space e viene usato per disegnare la prima metà del rettangolo.
  • La seconda metà del rettangolo viene disegnata nel normale colore rosso sRGB completamente saturo per il confronto.

Disegno di un colore largo in macOS

La NSImage classe è stata espansa in macOS Sierra per supportare il disegno di immagini Wide Color. Ad esempio:

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

Rendering delle immagini sullo schermo nell'app

Per eseguire il rendering di immagini a colori wide sullo schermo, il processo funziona in modo simile al disegno di un'immagine a colori fuori schermo per macOS e iOS presentata in precedenza.

Rendering su schermo in iOS

Quando l'app deve eseguire il rendering di un'immagine a colori wide sullo schermo in iOS, eseguire l'override del Draw metodo di in UIView questione come di consueto. Ad esempio:

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

Poiché iOS 10 fa con la UIGraphicsImageRenderer classe illustrata in precedenza, decide in modo intelligente se deve eseguire il rendering nello spazio colori sRGB o intervallo esteso sRGB in base alle funzionalità del dispositivo iOS in cui è in esecuzione l'app quando viene chiamato il Draw metodo. Inoltre, è UIImageView stato gestito dal colore anche da iOS 9.3.

Se l'app deve sapere come viene eseguito il rendering in un UIView oggetto o UIViewController, può controllare la nuova DisplayGamut proprietà della UITraitCollection classe . Questo valore sarà un'enumerazione UIDisplayGamut degli elementi seguenti:

  • P3
  • Srgb
  • Non specificato

Se l'app vuole controllare quale spazio colore viene usato per disegnare un'immagine, può usare una nuova ContentsFormat proprietà di CALayer per specificare lo spazio colore desiderato. Questo valore può essere un'enumerazione CAContentsFormat degli elementi seguenti:

  • Gray8Uint
  • Rgba16Float
  • Rgba8Uint

Rendering su schermo in macOS

Quando l'app deve eseguire il rendering di un'immagine a colori wide sullo schermo in macOS, eseguire l'override del DrawRect metodo di in NSView questione come di consueto. Ad esempio:

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

Anche in questo caso, decide in modo intelligente se deve eseguire il rendering nello spazio colore sRGB o intervallo esteso in base alle funzionalità dell'hardware Mac su cui è in esecuzione l'app quando viene chiamato il DrawRect metodo .

Se l'app vuole controllare quale spazio colore viene usato per disegnare un'immagine, può usare una nuova DepthLimit proprietà della NSWindow classe per specificare lo spazio colore desiderato. Questo valore può essere un'enumerazione NSWindowDepth degli elementi seguenti:

  • OneHundredTwentyEightBitRgb
  • SessantafourBitRgb
  • VentifourBitRgb