Široká barva v Xamarin.iOS
Tento článek popisuje širokou barvu a způsob použití v aplikaci Xamarin.iOS nebo Xamarin.Mac.
iOS 10 a macOS Sierra vylepšuje podporu pro formáty pixelů s rozšířeným rozsahem a široké barevné prostory v celém systému včetně architektur, jako jsou Core Graphics, Core Image, Metal a AVFoundation. Podpora zařízení s širokými barevnými displeji je dále jednodušší tím, že toto chování poskytuje v celém grafickém zásobníku.
V iOSu 10 a macOS Sierra společnost Apple rozšířila katalogy prostředků, které se používají k zahrnutí a kategorizaci statického obsahu obrázků v sadě aplikací, aby podporovala širokou barvu.
Používání katalogu prostředků poskytuje aplikaci následující výhody:
- Poskytují nejlepší možnost nasazení pro prostředky statických imagí.
- Podporují automatickou opravu barev.
- Podporují automatickou optimalizaci formátu pixelů.
- Podporují vytváření řezů aplikací a ztenčení aplikací, které zajišťují, že se do zařízení koncového uživatele doručí jenom obsah, který je relevantní.
Apple provedl následující vylepšení katalogu assetů pro širokou podporu barev:
- Podporují 16bitový (barevný kanál) zdrojového obsahu.
- Podporují katalogování obsahu podle gamutu zobrazení. Obsah může být označen pro gamuty sRGB nebo Display P3.
Vývojář má tři možnosti podpory širokého barevného obsahu ve svých aplikacích:
- Nedělat nic – protože široký barevný obsah by se měl používat jenom v situacích, kdy aplikace potřebuje zobrazovat živé barvy (kde zlepší uživatelské prostředí), obsah mimo tento požadavek by měl zůstat tak, jak je. Bude se dál vykreslovat správně ve všech hardwarových situacích.
- Upgrade existujícího obsahu na zobrazení P3 – To vyžaduje, aby vývojář nahradil existující obsah obrázku v katalogu prostředků novým upgradovaným souborem ve formátu P3 a označil ho jako takový v Editoru prostředků. V době sestavení se z těchto prostředků vygeneruje odvozená image sRGB.
- Poskytnout optimalizovaný obsah assetu – v této situaci vývojář poskytne 8bitovou sRGB i 16bitovou vizi P3 každého obrázku v katalogu assetů (správně označený v editoru prostředků).
Následující situace nastane, když vývojář odešle aplikaci do App Storu s katalogy prostředků, které obsahují široký barevný obsah obrázku:
- Když je aplikace nasazená pro koncového uživatele, řezy aplikací zajistí, že se do zařízení uživatele doručí jenom příslušná varianta obsahu.
- Na zařízení, které nepodporují širokou barvu, nejsou žádné náklady na datovou část pro zahrnutí širokého barevného obsahu, protože se do zařízení nikdy nedoručí.
NSImage
v systému macOS Sierra (a novější) automaticky vybere nejlepší reprezentaci obsahu pro displej hardwaru.- Zobrazený obsah se aktualizuje automaticky, pokud se změní vlastnosti hardwaru zařízení.
Úložiště katalogu assetů má následující vlastnosti a důsledky pro aplikaci:
- V době sestavení se Apple pokusí optimalizovat úložiště obsahu obrázku prostřednictvím vysoce kvalitních převodů obrázků.
- Pro široký barevný obsah se používá 16 bitů na barevný kanál.
- Komprese obrázků závislých na obsahu se používá k nižším velikostem obsahu dodávky. Byly přidány nové komprese pro ztrátu, aby se dále optimalizovaly velikosti obsahu.
Na základě typu vytvářené aplikace může uživateli umožnit 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í vylepšených funkcí přidaných do iOSu i macOS.
Než začnete diskutovat o tom, jak správně nakreslit široký barevný obrázek v iOSu 10, podívejte se na následující běžný kód 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ý bude potřeba vyřešit , než ho budete moct použít k vykreslení širokého barevného obrázku. Metoda UIGraphics.BeginImageContext (size)
použitá ke spuštění výkresu obrázků pro iOS má následující omezení:
- Nemůže vytvářet kontexty obrázků s více než 8 bity na barevný kanál.
- V barevném prostoru rozšířeného rozsahu sRGB nemůže reprezentovat barvy.
- Nemá schopnost poskytovat rozhraní pro vytváření kontextů v barevném prostoru bez sRGB, protože rutiny jazyka C nízké úrovně se volají na pozadí.
Pokud chcete tato omezení zpracovat 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á UIGraphicsImageRenderer
třída vytvoří nový kontext obrázku, který dokáže zpracovat barevný prostor sRGB Extended Range a má následující funkce:
- Ve výchozím nastavení je plně spravovaná barvou.
- Ve výchozím nastavení podporuje barevný prostor rozšířeného rozsahu sRGB.
- Inteligentně se rozhodne, jestli se má vykreslit v barevném prostoru sRGB nebo rozšířeném rozsahu sRGB na základě možností zařízení s iOSem, na kterém je aplikace spuštěná.
- Plně a automaticky spravuje kontext obrázku (
CGContext
), aby se vývojář nemusel starat o volání příkazů počátečního a koncového kontextu. - Je kompatibilní s metodou
UIGraphics.GetCurrentContext()
.
Metoda CreateImage
UIGraphicsImageRenderer
třídy je volána k vytvoření širokoúhlého barevného obrázku a předal obslužnou rutinu dokončení s kontextem obrázku, do které se má nakreslit. Celý výkres se provádí uvnitř této obslužné rutiny dokončení následujícím způsobem:
- Metoda
UIColor.FromDisplayP3
vytvoří novou plně nasycenou červenou barvu v širokém gamut displeji P3 Barevný prostor a použije se k vykreslení první poloviny obdélníku. - Druhá polovina obdélníku je nakreslena v normální sRGB plně nasycená červená barva pro porovnání.
Třída NSImage
byla v systému macOS Sierra rozšířena tak, aby podporovala kreslení obrázků s širokou barvou. Pří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;
});
Pokud chcete vykreslit širokobarevné obrázky na obrazovce, proces funguje podobně jako vykreslení barevného obrázku na celé obrazovce pro macOS a iOS uvedené výše.
Když aplikace potřebuje vykreslit obrázek v široké barvě na obrazovce v iOSu, přepište Draw
metodu UIView
otázky obvyklým způsobem. Pří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
...
}
}
}
Vzhledem k tomu, že iOS 10 provádí s UIGraphicsImageRenderer
třídou uvedenou výše, inteligentně se rozhodne, jestli se má vykreslit v barevném prostoru sRGB nebo rozšířeného rozsahu sRGB na základě možností zařízení s iOSem, na kterém aplikace běží při Draw
zavolání metody. Kromě toho se barva spravuje od iOSu UIImageView
9.3.
Pokud aplikace potřebuje vědět, jak se vykreslování provádí na objektu UIView
nebo UIViewController
, může zkontrolovat novou DisplayGamut
vlastnost UITraitCollection
třídy. Tato hodnota bude výčtem UIDisplayGamut
následujících:
- P3
- Srgb
- Nespecifikované
Pokud chce aplikace určit, který barevný prostor se používá k nakreslení obrázku, může použít novou ContentsFormat
vlastnost požadovaného barevného CALayer
prostoru. Tato hodnota může být výčtem CAContentsFormat
následujících:
- Gray8Uint
- Rgba16Float
- Rgba8Uint
Když aplikace potřebuje vykreslit obrázek v široké barvě na obrazovce v systému macOS, přepište DrawRect
metodu NSView
otázky obvyklým způsobem. Pří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
...
}
}
}
Opět se inteligentně rozhodne, jestli se má vykreslit v barevném prostoru sRGB nebo rozšířeného rozsahu sRGB na základě schopností hardwaru Mac, na kterém aplikace běží při DrawRect
zavolání metody.
Pokud chce aplikace určit, který barevný prostor se používá k vykreslení obrázku, může použít novou DepthLimit
vlastnost NSWindow
třídy k určení požadovaného barevného prostoru. Tato hodnota může být výčtem NSWindowDepth
následujících:
- OneHundredTwentyEightBitRgb
- SixtyfourBitRgb
- TwentyfourBitRgb