Široká barva v Xamarin.iOS

Tento článek se věnuje široké barvě a způsobu použití v aplikaci Xamarin.iOS nebo Xamarin.Mac.

iOS 10 a macOS Sierra vylepšují podporu formátů pixelů rozšířených rozsahů a širokých barevných prostorů v celém systému, včetně architektur, jako jsou základní grafika, základní obrázek, kov a AV Přichytá. Podpora zařízení se širokými barevnými zobrazeními je ještě snadnější díky tomu, že se toto chování poskytuje v celém grafickém zásobníku.

Katalogy prostředků

Podpora široké barvy pomocí katalogů prostředků

V iOSu 10 a macOS Sierra společnost Apple rozšířila katalogy assetů, které se používají k zahrnutí a kategorizaci statického obsahu obrázků v sadě aplikací pro podporu široké barvy.

Používání katalogů prostředků přináší aplikaci následující výhody:

  • Poskytují nejlepší možnost nasazení pro statické prostředky image.
  • Podporují automatickou opravu barev.
  • Podporují automatickou optimalizaci formátu pixelů.
  • Podporují funkce App Slicing a App Thinning, které zajišťují, že se do zařízení koncového uživatele doručí jenom relevantní obsah.

Apple provedl následující vylepšení katalogů assetů pro širokou podporu barev:

  • Podporují 16bitový zdrojový obsah (na barevný kanál).
  • Podporují katalogizaci obsahu zobrazením gamutu. Obsah je možné označit buď pro gamuty sRGB, nebo pro zobrazení P3.

Vývojář má tři možnosti pro podporu širokého barevného obsahu ve svých aplikacích:

  1. Nedělat nic – vzhledem k tomu, že široký barevný obsah by se měl používat jenom v situacích, kdy aplikace potřebuje zobrazit barevné barvy (kde vylepší uživatelské prostředí), měl by se obsah mimo tento požadavek nechat tak, jak je. Bude se dál správně vykreslovat ve všech situacích s hardwarem.
  2. Upgrade existujícího obsahu na Zobrazení P3 – Vývojář musí nahradit stávající obsah obrázku ve svém katalogu assetů novým upgradovaný souborem ve formátu P3 a označit ho jako takový v Editoru prostředků. V době sestavení se z těchto prostředků vygeneruje odvozená image sRGB.
  3. Poskytovat optimalizovaný obsah assetu – v této situaci poskytne vývojář 8bitový sRGB i 16bitový vizi zobrazení P3 každého obrázku v katalogu assetů (správně označený v editoru prostředků).

Nasazení katalogu assetů

K následujícímu chování dojde, když vývojář odešle aplikaci do služby App Store katalogy assetů, které obsahují široký obsah obrázků barev:

  • Když se aplikace nasadí koncovému uživateli, zajistí se tím, že se do zařízení uživatele doručí jenom odpovídající varianta obsahu.
  • Na zařízeních, která nepodporují širokou barvu, nejsou za zahrnutí širokého barevného obsahu žádné náklady na datovou část, protože se do zařízení nikdy nedodá.
  • NSImage v macOS Sierra (a novější) automaticky vybere nejlepší reprezentaci obsahu pro displej hardwaru.
  • Zobrazený obsah se automaticky aktualizuje, když se změní vlastnosti hardwarového zobrazení zařízení.

Asset Catalog Storage

Úložiště katalogu assetů má následující vlastnosti a důsledky pro aplikaci:

  • V době sestavování se Apple pokusí optimalizovat úložiště obsahu obrázku prostřednictvím vysoce kvalitních převodů obrázků.
  • Pro široký obsah barev se pro barevný kanál používá 16 bitů.
  • Komprese obrázků závislá na obsahu se používá k nižší velikosti obsahu, která je doručovatelná. Přidali jsme nové "ztrátové" komprese, které dále optimalizují velikosti obsahu.

Vykreslování Off-Screen obrázků v aplikaci

Na základě typu vytvářené aplikace může uživatel zahrnout obsah obrázku, který shromáždil z internetu, nebo vytvořit obsah obrázku přímo uvnitř aplikace (například aplikace pro vektorové kreslení).

V obou těchto případech může aplikace vykreslit požadované snímky mimo obrazovku v široké barvě pomocí rozšířených funkcí přidaných do iOSu i macOS.

Kreslení široké barvy v iOSu

Než probereme, jak správně nakreslit široký barevný obrázek v iOSu 10, podívejte se na následující běžný kód pro kreslení iOS:

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

    ...

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

Existují problémy se standardním kódem, které je potřeba vyřešit, než ho bude možné použít k nakreslení širokého barevného obrázku. Metoda UIGraphics.BeginImageContext (size) použitá ke spuštění kreslení iOS má následující omezení:

  • Nemůže vytvářet kontexty obrázků s více než 8 bity na barevný kanál.
  • Nemůže představovat barvy v barevném prostoru sRGB rozšířeného rozsahu.
  • Nemá možnost poskytovat rozhraní pro vytváření kontextů v barevném prostoru mimo sRGB kvůli rutinám jazyka C nízké úrovně, které jsou volány na pozadí.

Pokud chcete tato omezení zvládnout a nakreslit široký barevný obrázek v iOSu 10, použijte místo toho následující kód:

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

Nová třída vytvoří nový kontext obrázku, který dokáže zvládnout barevný prostor sRGB rozšířeného rozsahu UIGraphicsImageRenderer a má následující funkce:

  • Ve výchozím nastavení je plně spravovaná barvami.
  • Ve výchozím nastavení podporuje barevný prostor sRGB rozšířeného rozsahu.
  • Inteligentně se rozhodne, jestli se má vykreslit v barevném prostoru sRGB sRGB nebo rozšířeném rozsahu na základě možností zařízení s iOSem, na které je aplikace spuštěná.
  • Plně a automaticky spravuje životnost kontextu image ( ), takže se vývojář nemusí starat o volání příkazů počátečního a CGContext koncového kontextu.
  • Je kompatibilní s metodou UIGraphics.GetCurrentContext() .

Metoda třídy je volána k vytvoření širokého obrázku barvy a předána obslužná rutina dokončení s kontextem obrázku, do které CreateImageUIGraphicsImageRenderer se má nakreslit. Veškerý kreslení se provádí uvnitř této obslužné rutiny dokončení následujícím způsobem:

  • Metoda vytvoří novou plně sytou červenou barvu v širokém gamutu Barevného prostoru zobrazení P3 a použije se k nakreslení první UIColor.FromDisplayP3 poloviny obdélníku.
  • Druhá polovina obdélníku je vykreslena v normální sRGB plně syté červené barvě pro porovnání.

Kreslení široké barvy v macOS

Třída NSImage byla rozšířena v macOS Sierra, aby podporovala kreslení obrázků širokých barev. Například:

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

Vykreslování obrázků na obrazovce v aplikaci

Při vykreslování širokých barevných obrázků na obrazovce funguje proces podobně jako vykreslení barevného obrázku široké obrazovky pro macOS a iOS uvedeném výše.

Vykreslování na obrazovce v iOSu

Pokud aplikace potřebuje v iOSu vykreslit obrázek v široké barvě, přepište obvyklou metodu příslušné DrawUIView metody. Například:

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

Stejně jako iOS 10 se třídou uvedenou výše se inteligentně rozhodne, jestli se má vykreslit v barevném prostoru sRGB sRGB rozšířeného rozsahu na základě možností zařízení s iOSem, na které aplikace běží při volání UIGraphicsImageRendererDraw metody. Kromě toho se UIImageView od iOSu 9.3 spravuje také barva.

Pokud aplikace potřebuje vědět, jak se provádí vykreslování u třídy nebo , může zkontrolovat UIViewUIViewController novou vlastnost třídy DisplayGamutUITraitCollection . Tato hodnota bude UIDisplayGamut výčtem následujících hodnot:

  • P3
  • Srgb
  • Unspecified

Pokud chce aplikace určit, který barevný prostor se použije k kreslení obrázku, může k určení požadovaného barevného prostoru použít ContentsFormatCALayer novou vlastnost objektu . Tato hodnota může CAContentsFormat být výčtem následujících hodnot:

  • Gray8Uint
  • Rgba16Float
  • Rgba8Uint

Vykreslování na obrazovce v macOS

Když aplikace potřebuje v macOS vykreslit obrázek v široké barvě, přepište obvyklou metodu příslušné DrawRectNSView metody. Například:

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

Znovu se inteligentně rozhodne, jestli se má vykreslit v barevném prostoru sRGB nebo sRGB rozšířeného rozsahu na základě možností hardwaru Mac, na které aplikace běží při volání DrawRect metody.

Pokud chce aplikace určit, který barevný prostor se použije k kreslení obrázku, může k určení požadovaného barevného prostoru použít novou vlastnost DepthLimitNSWindow třídy . Tato hodnota může NSWindowDepth být výčtem následujících hodnot:

  • One VetyEightBitRgb
  • SixtyfourBitRgb
  • TwentyfourBitRgb