Xamarin.iOS의 와이드 색

이 문서에서는 넓은 색과 Xamarin.iOS 또는 Xamarin.Mac 앱에서 사용할 수 있는 방법을 설명합니다.

iOS 10 및 macOS Sierra는 코어 그래픽, 코어 이미지, 금속 및 AVFoundation과 같은 프레임워크를 포함하여 시스템 전체에서 확장 범위 픽셀 형식 및 와이드 영역 색 공간에 대한 지원을 향상시킵니다. 전체 그래픽 스택에서 이 동작을 제공하여 와이드 컬러 디스플레이가 있는 디바이스에 대한 지원을 더욱 쉽게 수행할 수 있습니다.

자산 카탈로그

자산 카탈로그를 사용하여 와이드 컬러 지원

iOS 10 및 macOS Sierra에서 Apple은 와이드 컬러를 지원하기 위해 앱 번들에 정적 이미지 콘텐츠를 포함하고 분류하는 데 사용되는 자산 카탈로그를 확장했습니다.

자산 카탈로그를 사용하면 앱에 다음과 같은 이점이 제공됩니다.

  • 정적 이미지 자산에 가장 적합한 배포 옵션을 제공합니다.
  • 자동 색 보정을 지원합니다.
  • 자동 픽셀 형식 최적화를 지원합니다.
  • 앱 조각화 및 앱 씬닝을 지원하여 관련 콘텐츠만 최종 사용자의 디바이스에 배달되도록 합니다.

Apple은 다양한 색상 지원을 위해 자산 카탈로그를 다음과 같이 개선했습니다.

  • 16비트(색 채널당) 원본 콘텐츠를 지원합니다.
  • 디스플레이 영역을 통해 카탈로그 콘텐츠를 지원합니다. sRGB 또는 디스플레이 P3 영역을 위해 콘텐츠에 태그를 지정할 수 있습니다.

개발자는 앱에서 와이드 컬러 콘텐츠를 지원하는 세 가지 옵션을 제공합니다.

  1. Do Nothing - 와이드 컬러 콘텐츠는 앱이 선명한 색을 표시해야 하는 경우에만 사용해야 하므로(사용자의 환경을 향상시키는 경우) 이 요구 사항 이외의 콘텐츠는 있는 그대로 두어야 합니다. 모든 하드웨어 상황에서 계속 올바르게 렌더링됩니다.
  2. 기존 콘텐츠를 P3 표시로 업그레이드 - 이를 위해서는 개발자가 자산 카탈로그의 기존 이미지 콘텐츠를 P3 형식의 업그레이드된 새 파일로 바꾸고 자산 편집기에서처럼 태그를 지정해야 합니다. 빌드 시 이러한 자산에서 sRGB 파생 이미지가 생성됩니다.
  3. 최적화된 자산 콘텐츠 제공 - 이 경우 개발자는 자산 카탈로그의 각 이미지에 대한 8비트 sRGB 및 16비트 디스플레이 P3 비전을 모두 제공합니다(자산 편집기에서 제대로 태그가 지정됨).

자산 카탈로그 배포

개발자가 와이드 컬러 이미지 콘텐츠를 포함하는 자산 카탈로그를 사용하여 앱 스토어에 앱을 제출할 때 다음이 발생합니다.

  • 앱이 최종 사용자에게 배포되면 App Slicing은 적절한 콘텐츠 변형만 사용자의 디바이스에 전달되도록 합니다.
  • 와이드 컬러를 지원하지 않는 디바이스에서는 디바이스에 배송되지 않으므로 와이드 컬러 콘텐츠를 포함하기 위한 페이로드 비용이 없습니다.
  • NSImage macOS Sierra 이상에서는 하드웨어 디스플레이에 가장 적합한 콘텐츠 표현을 자동으로 선택합니다.
  • 디바이스 하드웨어 디스플레이 특성이 변경되면 표시된 콘텐츠가 자동으로 새로 고쳐집니다.

자산 카탈로그 Storage

Asset Catalog 스토리지에는 앱에 대한 다음과 같은 속성과 의미가 있습니다.

  • 빌드 시 Apple은 고품질 이미지 변환을 통해 이미지 콘텐츠의 스토리지를 최적화하려고 합니다.
  • 와이드 컬러 콘텐츠의 경우 색 채널당 16비트가 사용됩니다.
  • 콘텐츠 종속 이미지 압축은 결과물 콘텐츠 크기를 줄이는 데 사용됩니다. 콘텐츠 크기를 더욱 최적화하기 위해 새로운 "손실" 압축이 추가되었습니다.

앱에서 Off-Screen 이미지 렌더링

생성되는 앱의 유형에 따라 사용자가 인터넷에서 수집한 이미지 콘텐츠를 포함하거나 앱 내에서 직접 이미지 콘텐츠를 만들 수 있습니다(예: 벡터 그리기 앱).

이 두 경우 모두 앱은 iOS 및 macOS 모두에 추가된 향상된 기능을 사용하여 필요한 이미지를 와이드 컬러로 오프스크린으로 렌더링할 수 있습니다.

iOS에서 와이드 컬러 그리기

iOS 10에서 와이드 컬러 이미지를 올바르게 그리는 방법을 알아보기 전에 다음 일반적인 iOS 그리기 코드를 살펴보세요.

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

    ...

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

표준 코드는 넓은 색 이미지를 그리는 데 사용 되기 전에 해결해야 하는 문제가 있습니다. UIGraphics.BeginImageContext (size) iOS 이미지 그리기를 시작하는 데 사용되는 메서드에는 다음과 같은 제한 사항이 있습니다.

  • 색 채널당 8비트가 넘는 이미지 컨텍스트를 만들 수 없습니다.
  • 확장 범위 sRGB 색 공간에서 색을 나타낼 수 없습니다.
  • 백그라운드에서 호출되는 하위 수준 C 루틴 때문에 비 sRGB 색 공간에서 컨텍스트를 만드는 인터페이스를 제공할 수 없습니다.

이러한 제한을 처리하고 iOS 10에서 와이드 컬러 이미지를 그리려면 대신 다음 코드를 사용합니다.

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

UIGraphicsImageRenderer 클래스는 확장 범위 sRGB 색 공간을 처리할 수 있는 새 이미지 컨텍스트를 만들고 다음과 같은 기능을 제공합니다.

  • 기본적으로 완전 색으로 관리됩니다.
  • 기본적으로 확장 범위 sRGB 색 공간을 지원합니다.
  • 앱이 실행 중인 iOS 디바이스의 기능에 따라 sRGB 또는 확장 범위 sRGB 색 공간에서 렌더링할지 여부를 지능적으로 결정합니다.
  • 개발자는 시작 및 끝 컨텍스트 명령을 호출하는 것에 대해 걱정할 필요가 없도록 이미지 컨텍스트(CGContext) 수명을 완전하고 자동으로 관리합니다.
  • 메서드와 호환됩니다 UIGraphics.GetCurrentContext() .

CreateImage 클래스의 UIGraphicsImageRenderer 메서드는 넓은 색 이미지를 만들기 위해 호출되고 그릴 이미지 컨텍스트를 사용하여 완성 처리기를 전달합니다. 모든 그리기는 다음과 같이 이 완료 처리기 내에서 수행됩니다.

  • 이 메서드는 UIColor.FromDisplayP3 넓은 영역 표시 P3 색 공간에 완전히 포화된 새 빨간색을 만들고 사각형의 첫 번째 절반을 그리는 데 사용됩니다.
  • 사각형의 후반부가 비교를 위해 일반 sRGB 완전히 포화된 빨간색으로 그려집니다.

macOS에서 와이드 컬러 그리기

클래스는 NSImage 와이드 컬러 이미지 그리기를 지원하기 위해 macOS Sierra에서 확장되었습니다. 예를 들어:

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

앱에서 화상 이미지 렌더링

화면에 와이드 컬러 이미지를 렌더링하기 위해 이 프로세스는 위에 표시된 macOS 및 iOS에 대한 오프스크림 와이드 컬러 이미지를 그리는 것과 유사하게 작동합니다.

iOS에서 화상 렌더링

앱이 iOS에서 화면의 넓은 색으로 이미지를 렌더링해야 하는 경우 해당 메서드를 UIView 평소와 같이 재정 Draw 의합니다. 예를 들어:

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

iOS 10은 위에 표시된 클래스와 UIGraphicsImageRenderer 마찬가지로 메서드가 호출될 때 Draw 앱이 실행되는 iOS 디바이스의 기능을 기반으로 sRGB 또는 확장 범위 sRGB 색 공간에서 렌더링할지 여부를 지능적으로 결정합니다. UIImageView 또한 iOS 9.3부터 색이 관리되었습니다.

앱에서 렌더링이 수행 UIView 되는 방법을 알아야 하는 경우 또는 UIViewController클래스의 UITraitCollectionDisplayGamut 속성을 확인할 수 있습니다. 이 값은 다음 열거형이 됩니다 UIDisplayGamut .

  • P3
  • Srgb
  • Unspecified

앱이 이미지를 그리는 데 사용되는 색 공간을 제어하려는 경우 원하는 색 공간을 지정하는 데 새 ContentsFormat 속성을 CALayer 사용할 수 있습니다. 이 값은 CAContentsFormat 다음 열거형일 수 있습니다.

  • Gray8Uint
  • Rgba16Float
  • Rgba8Uint

macOS에서 화상 렌더링

앱이 macOS에서 화면의 넓은 색으로 이미지를 렌더링해야 하는 경우 해당 메서드를 NSView 평소와 같이 재정 DrawRect 의합니다. 예를 들어:

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

다시 말하지만, 메서드가 호출될 때 DrawRect 앱이 실행되는 Mac 하드웨어의 기능에 따라 sRGB 또는 확장 범위 sRGB 색 공간에서 렌더링할지 여부를 지능적으로 결정합니다.

앱이 이미지를 그리는 데 사용되는 색 공간을 제어하려는 경우 클래스의 NSWindowDepthLimit 속성을 사용하여 원하는 색 공간을 지정할 수 있습니다. 이 값은 NSWindowDepth 다음 열거형일 수 있습니다.

  • OneHundredTwentyEightBitRgb
  • SixtyfourBitRgb
  • TwentyfourBitRgb