금속을 기반으로 한 이미지 처리 프레임 워크.
MTIImage 만듭니다MTIImage 렌더링하십시오MTIImage 표시하십시오CVPixelBuffer 의 컬러 스페이스SwiftAppleSiliconMetalPetal은 사용하기 쉬운 프로그래밍 인터페이스를 통해 정지 이미지 및 비디오에 실시간 처리를 제공하도록 설계된 금속을 기반으로 한 이미지 처리 프레임 워크입니다.
이 장에서는 MetalPetal의 주요 개념을 다루며 설계, 구현, 성능 영향 및 모범 사례를 더 잘 이해하는 데 도움이됩니다.
MetalPetal은 다음 목표를 염두에두고 설계되었습니다.
사용하기 쉬운 API
편의 API를 제공하고 일반적인 함정을 피합니다.
성능
CPU, GPU 및 메모리를 효율적으로 사용하십시오.
확장 성
사용자 정의 필터를 쉽게 만들고 사용자 정의 이미지 처리 장치를 플러그인 할 수 있습니다.
신어
신속한 프로그래머에게 유동적 인 경험을 제공합니다.
MetalPetal의 핵심 개념 중 일부는 Apple의 핵심 이미지 프레임 워크와 매우 유사합니다.
MTIImage s를 렌더링하기위한 평가 컨텍스트를 제공합니다. 또한 많은 캐시와 상태 정보를 저장하므로 가능할 때마다 컨텍스트를 재사용하는 것이 더 효율적입니다.
MTIImage 객체는 처리되거나 생성 할 이미지를 표현한 것입니다. MTLTexture 이미지 비트 맵 데이터를 직접 표시합니다. 텍스처를 생성하는 방법 ( MTIImagePromise )의 레시피 및 컨텍스트가 이미지를 캐시하는 방법 ( cachePolicy ) 및 텍스처 샘플링 방법 ( samplerDescriptor )과 같은 두 부분으로 구성됩니다.
MTIFilter 이미지 처리 효과 및 해당 효과를 제어하는 매개 변수를 나타냅니다. 출력으로 MTIImage 객체를 생성합니다. 필터를 사용하려면 필터 객체를 만들고 입력 이미지와 매개 변수를 설정 한 다음 출력 이미지에 액세스하십시오. 일반적으로 필터 클래스는 정적 커널 ( MTIKernel )을 소유하고, outputImage 속성에 액세스 할 때 입력 이미지 및 매개 변수가있는 커널을 요청하여 출력 MTIImage 생성합니다.
MTIKernel 이미지 처리 루틴을 나타냅니다. MTIKernel 필터의 해당 렌더링 또는 컴퓨팅 파이프 라인 상태를 작성하고 MTIImage 위한 MTIImagePromise 구축 할 책임이 있습니다.
MetalPetal은 후드 아래에서 많은 최적화를 수행합니다.
기능, 커널 상태, 샘플러 상태 등을 자동으로 캐시합니다.
프로그래밍 가능한 블렌딩, 메모리리스 렌더링 대상, 리소스 힙 및 금속 성능 셰이더와 같은 금속 기능을 사용하여 렌더링을 빠르고 효율적으로 만듭니다. MACOS에서 MetalPetal은 Apple Silicon의 TBDR 아키텍처를 활용할 수 있습니다.
렌더링하기 전에 MetalPetal은 이미지 렌더 그래프를보고 렌더링, 메모리, 에너지 및 시간을 저장하는 데 필요한 최소한의 중간 텍스처를 파악할 수 있습니다.
또한 중복 렌더 패스를 제거하기 위해 여러 "레시피"를 연결할 수있는 경우 이미지 렌더 그래프를 재구성 할 수 있습니다. ( MTIContext.isRenderGraphOptimizationEnabled )
MTIImage 객체는 불변이기 때문에 스레드간에 안전하게 공유 할 수 있습니다.
그러나 MTIFilter 객체는 변이 가능하므로 스레드간에 안전하게 공유 할 수 없습니다.
MTIContext 에는 많은 상태와 캐시가 포함되어 있습니다. MTIContext 객체에 대한 스레드 안전 메커니즘이있어 스레드간에 MTIContext 객체를 공유하는 것이 안전합니다.
완전히 사용자 정의 가능한 정점 및 조각 기능.
MRT (다중 렌더 대상) 지원.
일반적으로 더 나은 성능. (필요한 벤치 마크 데이터가 필요)
컬러 매트릭스
색상 조회
색상 조회 테이블을 사용하여 이미지의 색상을 다시 매핑합니다.
불투명
노출
포화
명도
차이
색상 반전
진동
즐거운 피부 색조를 유지하면서 이미지의 채도를 조정합니다.
RGB 톤 곡선
혼합 모드
마스크와 혼합하십시오
변환
수확고
픽셀 레이트
다층 복합재
MPS 컨볼 루션
MPS 가우시안 블러
MPS 정의
MPS Sobel
MPS UNSHARP 마스크
MPS 박스 블러
고지대 피부 스무딩
Clahe (대비 제한 적응 형 히스토그램 이퀄라이제이션)
렌즈 블러 (vexagonal bokeh blur)
표면 흐림
팽창 왜곡
크로마 키 블렌드
컬러 하프톤
도트 화면
둥근 코너 (원형/연속 곡선)
모든 핵심 이미지 필터
MTIImage 만듭니다 다음을 포함하여 거의 모든 이미지 데이터 소스에서 MTIImage 객체를 만들 수 있습니다.
URL 은로드 할 이미지 파일을 참조합니다CVImageBufferRef 또는 CVPixelBufferRef )CIImage 객체MDLTexture 객체 let imageFromCGImage = MTIImage ( cgImage : cgImage , isOpaque : true )
let imageFromCIImage = MTIImage ( ciImage : ciImage )
let imageFromCoreVideoPixelBuffer = MTIImage ( cvPixelBuffer : pixelBuffer , alphaType : . alphaIsOne )
let imageFromContentsOfURL = MTIImage ( contentsOf : url )
// unpremultiply alpha if needed
let unpremultipliedAlphaImage = image . unpremultiplyingAlpha ( ) let inputImage = ...
let filter = MTISaturationFilter ( )
filter . saturation = 0
filter . inputImage = inputImage
let outputImage = filter . outputImageMTIImage 렌더링하십시오 let options = MTIContextOptions ( )
guard let device = MTLCreateSystemDefaultDevice ( ) , let context = try ? MTIContext ( device : device , options : options ) else {
return
}
let image : MTIImage = ...
do {
try context . render ( image , to : pixelBuffer )
//context.makeCIImage(from: image)
//context.makeCGImage(from: image)
} catch {
print ( error )
}MTIImage 표시하십시오 let imageView = MTIImageView ( frame : self . view . bounds )
// You can optionally assign a `MTIContext` to the image view. If no context is assigned and `automaticallyCreatesContext` is set to `true` (the default value), a `MTIContext` is created automatically when the image view renders its content.
imageView . context = ...
imageView . image = image 기본 스레드에서 GPU 명령 인코딩 프로세스를 이동하려면 MTIThreadSafeImageView 를 사용할 수 있습니다. 모든 스레드에서 MTIThreadSafeImageView 에 MTIImage 할당 할 수 있습니다.
MetalPetal에는 연결 필터를위한 타입 안전 신속한 API가 있습니다. FilterGraph.makeImage 함수에서 => 연산자를 사용할 수 있습니다. 필터를 연결하고 출력 이미지를 가져옵니다.
몇 가지 예는 다음과 같습니다.
let image = try ? FilterGraph . makeImage { output in
inputImage => saturationFilter => exposureFilter => output
} let image = try ? FilterGraph . makeImage { output in
inputImage => saturationFilter => exposureFilter => contrastFilter => blendFilter . inputPorts . inputImage
exposureFilter => blendFilter . inputPorts . inputBackgroundImage
blendFilter => output
} => 사용하여 직접 단일 필터 ( MTIUnaryFilter )를 연결할 수 있습니다.
여러 입력이있는 필터의 경우 inputPorts 중 하나에 연결해야합니다.
=> 연산자는 FilterGraph.makeImage 메소드에서만 작동합니다.
하나의 필터 출력은 output 에 연결할 수 있습니다.
AVPlayer 와의 작업 :
let context = try MTIContext ( device : device )
let asset = AVAsset ( url : videoURL )
let composition = MTIVideoComposition ( asset : asset , context : context , queue : DispatchQueue . main , filter : { request in
return FilterGraph . makeImage { output in
request . anySourceImage! => filterA => filterB => output
} !
}
let playerItem = AVPlayerItem ( asset : asset )
playerItem . videoComposition = composition . makeAVVideoComposition ( )
player . replaceCurrentItem ( with : playerItem )
player . play ( )비디오 내보내기 :
다음 예제에는 videoio가 필요합니다.
import VideoIO
var configuration = AssetExportSession . Configuration ( fileType : . mp4 , videoSettings : . h264 ( videoSize : composition . renderSize ) , audioSettings : . aac ( channels : 2 , sampleRate : 44100 , bitRate : 128 * 1000 ) )
configuration . videoComposition = composition . makeAVVideoComposition ( )
self . exporter = try ! AssetExportSession ( asset : asset , outputURL : outputURL , configuration : configuration )
exporter . export ( progress : { progress in
} , completion : { error in
} )이 예제에는 videoio가 필요합니다.
import VideoIO
// Setup Image View
let imageView = MTIImageView ( frame : self . view . bounds )
...
// Setup Camera
let camera = Camera ( captureSessionPreset : . hd1920x1080 , configurator : . portraitFrontMirroredVideoOutput )
try camera . enableVideoDataOutput ( on : DispatchQueue . main , delegate : self )
camera . videoDataOutput ? . videoSettings = [ kCVPixelBufferPixelFormatTypeKey as String : kCVPixelFormatType_420YpCbCr8BiPlanarFullRange ]
...
// AVCaptureVideoDataOutputSampleBufferDelegate
let filter = MTIColorInvertFilter ( )
func captureOutput ( _ output : AVCaptureOutput , didOutput sampleBuffer : CMSampleBuffer , from connection : AVCaptureConnection ) {
guard let pixelBuffer = CMSampleBufferGetImageBuffer ( sampleBuffer ) else {
return
}
let inputImage = MTIImage ( cvPixelBuffer : pixelBuffer , alphaType : . alphaIsOne )
filter . inputImage = inputImage
self . imageView . image = filter . outputImage
} 필터링 된 라이브 비디오 미리보기 및 녹음에 대한 자세한 내용은 예제 프로젝트의 CameraFilterView.swift 를 참조하십시오.
가능할 때마다 MTIContext 재사용하십시오.
컨텍스트는 헤비급 객체이므로, 하나를 만들면 가능한 빨리 그렇게하고 이미지를 렌더링해야 할 때마다 재사용하십시오.
MTIImage.cachePolicy 현명하게 사용하십시오.
이미지의 렌더 결과 MTIImageCachePolicyTransient 보존하지 않으려는 경우, 예를 들어 이미지가 필터 체인이 중간 결과 인 경우 렌더링 결과의 기본 텍스처를 재사용 할 수 있습니다. 가장 메모리 효율적인 옵션입니다. 그러나 이전에 렌더링 된 이미지를 렌더링하도록 컨텍스트를 요청하면 기본 텍스처가 재사용되었으므로 해당 이미지를 다시 렌더링 할 수 있습니다.
기본적으로 필터의 출력 이미지에는 transient 정책이 있습니다.
기본 텍스처가 재사용되는 것을 방지 할 때 MTIImageCachePolicyPersistent 사용하십시오.
기본적으로 외부 소스에서 생성 된 이미지에는 persistent 정책이 있습니다.
MTIFilter.outputImage 는 컴퓨팅 속성임을 이해하십시오.
출력 이미지를 필터에 요청할 때마다 입력이 이전 호출과 동일하더라도 필터에 새 출력 이미지 객체를 제공 할 수 있습니다. 따라서 가능할 때마다 출력 이미지를 재사용하십시오.
예를 들어,
// ╭→ filterB
// filterA ─┤
// ╰→ filterC
//
// filterB and filterC use filterA's output as their input.이 상황에서 다음 해결책은 다음과 같습니다.
let filterOutputImage = filterA . outputImage
filterB . inputImage = filterOutputImage
filterC . inputImage = filterOutputImage보다 낫다 :
filterB . inputImage = filterA . outputImage
filterC . inputImage = filterA . outputImage MTIShaderLib.h .metal 파일에 포함 시키려면 MTIShaderLib.h 파일의 경로를 Metal Compiler - Header Search Paths ( MTL_HEADER_SEARCH_PATHS ) 설정에 추가해야합니다.
예를 들어, Cocoapods를 사용하는 경우 MTL_HEADER_SEARCH_PATHS ${PODS_CONFIGURATION_BUILD_DIR}/MetalPetal/MetalPetal.framework/Headers 또는 ${PODS_ROOT}/MetalPetal/Frameworks/MetalPetal/Shaders 로 설정할 수 있습니다. Swift 패키지 관리자를 사용하는 경우 MTL_HEADER_SEARCH_PATHS $(HEADER_SEARCH_PATHS) 로 설정하십시오.
MetalPetal에는 셰이더 기능 인수를 인코딩하는 내장 메커니즘이 있습니다. 셰이더 함수 인수를 name: value 사전 MTIRenderCommand(kernel:geometry:images:parameters:) 전달할 수 있습니다 MTIRenderPipelineKernel.apply(toInputImages:parameters:outputDescriptors:)
예를 들어, 금속 함수 vibranceAdjust 의 매개 변수 사전은 다음과 같습니다.
// Swift
let amount : Float = 1.0
let vibranceVector = float4 ( 1 , 1 , 1 , 1 )
let parameters = [ " amount " : amount ,
" vibranceVector " : MTIVector ( value : vibranceVector ) ,
" avoidsSaturatingSkinTones " : true ,
" grayColorTransform " : MTIVector ( value : float3 ( 0 , 0 , 0 ) ) ] // vibranceAdjust metal function
fragment float4 vibranceAdjust (...,
constant float & amount [[ buffer( 0 ) ]],
constant float4 & vibranceVector [[ buffer( 1 ) ]],
constant bool & avoidsSaturatingSkinTones [[ buffer( 2 ) ]],
constant float3 & grayColorTransform [[ buffer( 3 ) ]])
{
...
}
매개 변수 사전에서 사용할 셰이더 기능 인수 유형 및 해당 유형은 아래에 나열되어 있습니다.
| 셰이더 기능 인수 유형 | 스위프트 | 대상 c |
|---|---|---|
| 뜨다 | 뜨다 | 뜨다 |
| int | int32 | int |
| uint | UINT32 | uint |
| 부 | 부 | 부 |
| simd (float2, float4, float4x4, int4 등) | SIMD ( MetalPetal/Swift ) / mtivector | MTIVECTOR |
| 구조 | 데이터 / mtidatabuffer | nsdata / mtidatabuffer |
| 기타 (float *, struct *등) 불변 | 데이터 / mtidatabuffer | nsdata / mtidatabuffer |
| 기타 (float *, struct *등) Mutable | mtidatabuffer | mtidatabuffer |
사용자 정의 단지 필터를 만들려면 MTIUnaryImageRenderingFilter 서브 클래스하고 SubclassingHooks 카테고리에서 메소드를 대체 할 수 있습니다. 예 : MTIPixellateFilter , MTIVibranceFilter , MTIUnpremultiplyAlphaFilter , MTIPremultiplyAlphaFilter 등
// Objective-C
@interface MTIPixellateFilter : MTIUnaryImageRenderingFilter
@property ( nonatomic ) float fractionalWidthOfAPixel;
@end
@implementation MTIPixellateFilter
- ( instancetype ) init {
if (self = [ super init ]) {
_fractionalWidthOfAPixel = 0.05 ;
}
return self;
}
+ (MTIFunctionDescriptor *) fragmentFunctionDescriptor {
return [[MTIFunctionDescriptor alloc ] initWithName: @" pixellateEffect " libraryURL: [bundle URLForResource: @" default " withExtension: @" metallib " ]];
}
- ( NSDictionary <NSString *,id> *) parameters {
return @{ @" fractionalWidthOfAPixel " : @(self. fractionalWidthOfAPixel )};
}
@end //Swift
class MTIPixellateFilter : MTIUnaryImageRenderingFilter {
var fractionalWidthOfAPixel : Float = 0.05
override var parameters : [ String : Any ] {
return [ " fractionalWidthOfAPixel " : fractionalWidthOfAPixel ]
}
override class func fragmentFunctionDescriptor ( ) -> MTIFunctionDescriptor {
return MTIFunctionDescriptor ( name : " pixellateEffect " , libraryURL : MTIDefaultLibraryURLForBundle ( Bundle . main ) )
}
} 보다 복잡한 필터를 만들려면 커널 ( MTIRenderPipelineKernel / MTIComputePipelineKernel / MTIMPSKernel )을 작성한 다음 입력 이미지에 커널을 적용하기 만하면됩니다. 예 : MTIChromaKeyBlendFilter , MTIBlendWithMaskFilter , MTIColorLookupFilter 등
@interface MTIChromaKeyBlendFilter : NSObject <MTIFilter>
@property ( nonatomic , strong , nullable ) MTIImage *inputImage;
@property ( nonatomic , strong , nullable ) MTIImage *inputBackgroundImage;
@property ( nonatomic ) float thresholdSensitivity;
@property ( nonatomic ) float smoothing;
@property ( nonatomic ) MTIColor color;
@end
@implementation MTIChromaKeyBlendFilter
@synthesize outputPixelFormat = _outputPixelFormat;
+ (MTIRenderPipelineKernel *) kernel {
static MTIRenderPipelineKernel *kernel;
static dispatch_once_t onceToken;
dispatch_once (&onceToken, ^{
kernel = [[MTIRenderPipelineKernel alloc ] initWithVertexFunctionDescriptor: [[MTIFunctionDescriptor alloc ] initWithName: MTIFilterPassthroughVertexFunctionName] fragmentFunctionDescriptor: [[MTIFunctionDescriptor alloc ] initWithName: @" chromaKeyBlend " ]];
});
return kernel;
}
- ( instancetype ) init {
if (self = [ super init ]) {
_thresholdSensitivity = 0.4 ;
_smoothing = 0.1 ;
_color = MTIColorMake ( 0.0 , 1.0 , 0.0 , 1.0 );
}
return self;
}
- (MTIImage *) outputImage {
if (!self. inputImage || !self. inputBackgroundImage ) {
return nil ;
}
return [ self .class.kernel applyToInputImages: @[ self .inputImage, self .inputBackgroundImage]
parameters: @{ @" color " : [MTIVector vectorWithFloat4: (simd_float4){self. color . red , self. color . green , self. color . blue ,self. color . alpha }],
@" thresholdSensitivity " : @(self. thresholdSensitivity ),
@" smoothing " : @(self. smoothing )}
outputTextureDimensions: MTITextureDimensionsMake2DFromCGSize ( self .inputImage.size)
outputPixelFormat: self .outputPixelFormat];
}
@end MTIRenderCommand 사용하여 하나의 렌더 패스로 여러 개의 드로우 호출을 발행 할 수 있습니다.
// Create a draw call with kernelA, geometryA, and imageA.
let renderCommandA = MTIRenderCommand ( kernel : self . kernelA , geometry : self . geometryA , images : [ imageA ] , parameters : [ : ] )
// Create a draw call with kernelB, geometryB, and imageB.
let renderCommandB = MTIRenderCommand ( kernel : self . kernelB , geometry : self . geometryB , images : [ imageB ] , parameters : [ : ] )
// Create an output descriptor
let outputDescriptor = MTIRenderPassOutputDescriptor ( dimensions : MTITextureDimensions ( width : outputWidth , height : outputHeight , depth : 1 ) , pixelFormat : . bgra8Unorm , loadAction : . clear , storeAction : . store )
// Get the output images, the output image count is equal to the output descriptor count.
let images = MTIRenderCommand . images ( byPerforming : [ renderCommandA , renderCommandB ] , outputDescriptors : [ outputDescriptor ] )한 번의 렌더 패스 (MRT, https://en.wikipedia.org/wiki/multiple_render_targets 참조)에서 여러 이미지를 출력 할 수있는 여러 출력 설명자를 작성할 수도 있습니다.
MTIVertex 귀하의 요구에 맞을 수없는 경우 MTIGeometry 프로토콜을 구현하여 사용자 정의 정점 데이터를 명령 인코더에 제공 할 수 있습니다.
MTIRenderCommand API를 사용하여 콜을 뽑고 사용자 정의 MTIGeometry 통과하십시오.
드문 시나리오에서는 기본 텍스처에 직접 액세스하거나 하나의 렌더링 패스로 여러 MP 커널을 사용하거나 3D 렌더링을 수행하거나 렌더 명령을 직접 인코딩 할 수 있습니다.
MTIImagePromise 프로토콜은 Metalpetal의 단계를 위해 기본 텍스처 및 렌더 컨텍스트에 직접 액세스 할 수 있습니다.
MTIImagePromise 프로토콜을 구현하여 새로운 입력 소스 또는 완전히 사용자 정의 처리 장치를 만들 수 있습니다. 그렇게하려면 추가 모듈을 가져와야합니다.
대상 c
@import MetalPetal.Extension;
스위프트
// CocoaPods
import MetalPetal.Extension
// Swift Package Manager
import MetalPetalObjectiveC.Extension
예를 들어 MTIComputePipelineKernel , MTICLAHELUTRecipe 또는 MTIImage 의 구현을 참조하십시오.
알파 채널이 이미지에 사용되는 경우, 사용 가능한 두 가지 일반적인 표현이 있습니다 : 비 배상 (스트레이트/비 연관) 알파, 그리고 전형적인 (관련) 알파.
배설적 인 알파를 사용하면 RGB 구성 요소는 픽셀의 색상을 나타내며 불투명도를 무시합니다.
Pimultiplied Alpha를 사용하면 RGB 구성 요소는 픽셀의 색상을 나타냅니다.
MetalPetal은 알파 유형을 명시 적으로 처리합니다. 이미지 생성 중에 올바른 알파 유형을 제공 할 책임이 있습니다.
MetalPetal에는 세 가지 알파 유형이 있습니다.
MTIAlphaType.nonPremultiplied : 이미지의 알파 값은 전형적이지 않습니다.
MTIAlphaType.premultiplied . premultiplied : 이미지의 알파 값은 전형적입니다.
MTIAlphaType.alphaIsOne : 이미지에는 알파 채널이 없거나 이미지가 불투명합니다.
일반적으로, CGImage , CVPixelBuffer 및 CIImage 객체에는 알파 채널이 전형화된다. MTIAlphaType.alphaIsOne 이미지가 불투명 한 경우, 예를 들어 카메라 피드의 CVPixelBuffer 또는 jpg 파일에서로드 된 CGImage 강력히 권장합니다.
MTIImage 에서 unpremultiplyingAlpha() 또는 premultiplyingAlpha() 호출하여 이미지의 알파 유형을 변환 할 수 있습니다.
성능의 이유로 Alpha Type 유효성 검사는 디버그 빌드에서만 발생합니다.
MetalPetal의 필터의 대부분은 배수가없는 알파와 불투명 한 이미지를 받아들이고 배수가없는 알파 이미지를 출력합니다.
outputAlphaType 속성이있는 필터는 모든 알파 유형의 입력을 허용합니다. 또한 출력 이미지의 알파 유형을 지정하기 위해 outputAlphaType 사용 할 수 있습니다.
예 : MTIBlendFilter , MTIMultilayerCompositingFilter , MTICoreImageUnaryFilter , MTIRGBColorSpaceConversionFilter
실제로 색상을 수정하지 않는 필터에는 패스 스루 알파 처리 규칙이 있습니다. 즉, 출력 이미지의 알파 유형이 입력 이미지와 동일하다는 것을 의미합니다.
예 : MTITransformFilter , MTICropFilter , MTIPixellateFilter , MTIBulgeDistortionFilter
알파 유형 및 알파 합성에 대한 자세한 내용은 Bartosz Ciechanowski 의이 놀라운 대화식 기사를 참조하십시오.
색상 공간은 이미지 처리에 필수적입니다. 빨간색, 녹색 및 파란색 구성 요소의 숫자 값은 색상 공간이없는 의미가 없습니다.
MetalPetal이 색상 공간을 처리하는 방식을 계속하기 전에 색상 공간이 무엇인지, 색상 값의 표현에 어떤 영향을 미치는지 알고 싶을 수도 있습니다. 웹에는 컬러 공간을 설명하는 기사가 많이 있습니다. 시작하기 위해 제안은 Bartosz Ciechanowski의 컬러 공간입니다.
다른 소프트웨어와 프레임 워크마다 색상 공간을 처리하는 방법이 다릅니다. 예를 들어, Photoshop에는 기본 SRGB IEC61966-2.1 작동 색상 공간이 있으며, 기본적으로 코어 이미지는 선형 SRGB 작업 색상 공간을 사용합니다.
금속 텍스처는 색상 공간 정보를 저장하지 않습니다. MetalPetal에서의 대부분의 색상 공간 처리는 입력 ( MTIImage(...) ) 및 이미지 데이터의 출력 ( MTIContext.render... ) 동안 발생합니다.
입력에 대한 색상 공간을 지정한다는 것은 MetalPetal이 텍스처를 생성하는 동안 소스 색상 값을 지정된 색상 공간으로 변환해야 함을 의미합니다.
URL 또는 CGImage 에서로드 할 때 MTICGImageLoadingOptions 사용하여 텍스처 데이터를 원하는 색상 공간을 지정할 수 있습니다. 이미지를로드 할 때 옵션을 지정하지 않으면 장치 RGB 색상 공간이 사용됩니다 ( MTICGImageLoadingOptions.default ). nil 색상 공간은 색상 일치를 비활성화합니다. 이것은 입력 이미지의 색상 공간을 사용하여 MTICGImageLoadingOptions 생성하는 것과 같습니다. 지정된 색상 공간의 모델이 RGB가 아닌 경우 장치 RGB 색상 공간은 폴백으로 사용됩니다.
CIImage 에서로드 할 때 MTICIImageRenderingOptions 사용하여 텍스처 데이터를 원하는 색상 공간을 지정할 수 있습니다. CIImage 로드 할 때 옵션을 지정하지 않으면 장치 RGB 색상 공간이 사용됩니다 ( MTICIImageRenderingOptions.default ). nil 색상 공간은 색상 일치를 비활성화하고 색상 값은 CIContext 의 작동 색상 공간에로드됩니다.
출력을위한 색상 공간을 지정할 때, 색상 공간은 출력의 색상 값을 나타내는 방법에 대해 다른 시스템과 통신하는 데 사용되는 태그와 더 유사합니다. 실제 색상 공간 변환은 수행되지 않습니다.
MTIContext.makeCGImage... 또는 MTIContext.startTaskTo... colorSpace 공간 매개 변수가있는 메소드를 사용하여 출력 CGImage 의 색상 공간을 지정할 수 있습니다.
MTICIImageCreationOptions 사용하여 출력 CIImage 의 색상 공간을 지정할 수 있습니다.
MetalPetal은 출력 색상 값이 출력 색상 공간이 지정되지 않은 경우 장치 RGB 색상 공간에 있다고 가정합니다.
CVPixelBuffer 의 컬러 스페이스 Metalpetal은 CVMetalTextureCache 및 IOSurface 사용하여 CVPixelBuffer s를 금속 텍스처에 직접 매핑합니다. 따라서 CVPixelBuffer 에서로드하거나 렌더링하기위한 색상 공간을 지정할 수 없습니다. 그러나 매핑을 위해 SRGB 픽셀 형식으로 텍스처를 사용할지 여부를 지정할 수 있습니다.
금속에서 픽셀 형식 이름에 _sRGB 접미사가있는 경우 픽셀의 색상 값을 읽고 쓰는 동안 SRGB 감마 압축 및 감압이 적용됩니다. 즉, _sRGB 픽셀 형식의 텍스처는 저장소 값이 SRGB Gamma가 수정되었다고 가정합니다. 색상 값이 셰이더에서 읽히면 SRGB에서 선형 RGB 변환이 수행됩니다. 색상 값이 셰이더로 작성되면 선형 RGB에서 SRGB 변환이 수행됩니다.
MTIRGBColorSpaceConversionFilter 사용하여 색상 공간 변환을 수행 할 수 있습니다. 색상 공간 변환 기능은 MTIShaderLib.h 에서도 제공됩니다.
metalpetal::sRGBToLinear (SRGB IEC61966-2.1에서 선형 SRGB)metalpetal::linearToSRGB (선형 srgb에서 srgb IEC61966-2.1)metalpetal::linearToITUR709 (선형 SRGB에서 ITU-R 709)metalpetal::ITUR709ToLinear (ITU-R 709에서 선형 SRGB) MTISCNSceneRenderer 사용하여 SCNScene 에서 MTIImage s를 생성 할 수 있습니다. SceneeKit 렌더러의 선형 RGB 색상 공간을 처리 할 수 있습니다. 문제 #76 SceneKit의 이미지는 정상보다 어둡습니다.
MTISKSceneRenderer 사용하여 SKScene 에서 MTIImage s를 생성 할 수 있습니다.
CIImage s에서 MTIImage s를 만들 수 있습니다.
MTIContext 사용하여 MTIImage CIImage 에 렌더링 할 수 있습니다.
MTICoreImageKernel 또는 MTICoreImageUnaryFilter 클래스와 함께 직접 CIFilter 사용할 수 있습니다. (스위프트 만 해적)
MetalPetaljs를 참조하십시오
MetalPetaljs를 사용하면 JavaScript를 사용하여 렌더링 파이프 라인 및 필터를 만들 수 있으므로 "Cloud"에서 필터/렌더러를 다운로드 할 수 있습니다.
MTICGImageLoadingOptions MTKTextureLoaderOption 하는 API를 사용하는 대신 CGImage 를 허용하는 API를 사용하여 URL 에서 이미지를로드하는 것이 좋습니다.
MTKTextureLoaderOption 허용하는 API를 사용하는 경우, MetalPetal은 기본적으로 MTIDefaultTextureLoader 사용하여 CGImage S, URL 의 이미지 및 명명 된 이미지를로드합니다. MTIDefaultTextureLoader 내부적으로 MTKTextureLoader 사용하며 소량의 성능 비용으로 MTKTextureLoader 의 불일치 및 버그에 대한 해결 방법이 있습니다. MTITextureLoader 프로토콜을 구현하여 고유 한 텍스처 로더를 만들 수도 있습니다. 그런 다음 MTIContext 만들 때 텍스처 로더 클래스를 MTIContextOptions.textureLoaderClass 에 할당하십시오.
Cocoapod를 사용하여 최신 버전을 설치할 수 있습니다.
use_frameworks!
pod 'MetalPetal'
# Required if you are using Swift.
pod 'MetalPetal/Swift'
# Recommended if you'd like to run MetalPetal on Apple silicon Macs.
pod 'MetalPetal/AppleSilicon'
SwiftSwift에 대한 매핑을 개선하기 위해 대물 픽 C API에 신속한 특정 추가 및 수정을 제공합니다. Swift를 사용하는 경우 적극 권장합니다.
AppleSiliconApple Silicon Mac에서 프로그래밍 가능한 블렌딩 지원을 활성화하는 데 필요한 금속 음영 언어 v2.3으로 컴파일 된 기본 셰이더 라이브러리를 제공합니다.
앱에 패키지 종속성 추가
MetalPetal은 Xcode 11+ 및 MacOS 10.15+로 시뮬레이터에서 실행할 수 있습니다.
MetalPerformanceShaders.framework 는 시뮬레이터에서 사용할 수 없으므로 MTIMPSGaussianBlurFilter , MTICLAHEFilter 와 같은 MetalPerformanceShaders 에 의존하는 필터는 작동하지 않습니다.
시뮬레이터는 실제 Apple GPU보다 적은 기능이나 다른 구현 한도를 지원합니다. 세부 사항은 시뮬레이터에서 실행되는 금속 앱 개발을 참조하십시오.
MTIImage 를 빠르게 살펴보면 해당 이미지를 생성하기 위해 구성한 이미지 그래프를 표시합니다.

왜 객관적인 C인가?
MetalPetal에 기여하는 것을 고려해 주셔서 감사합니다. 기고 가이드 라인을 읽으십시오.
MetalPetal은 미트 라이센스가 있습니다. 특허
/MetalPetalExamples 디렉토리의 파일은 별도의 라이센스로 라이센스가 부여됩니다. 라이센스 .md
문서는 라이센스가 부여 된 CC-By-4.0입니다.