Kerangka pemrosesan gambar berdasarkan logam.
MTIImageMTIImageMTIImageCVPixelBufferSwiftAppleSiliconMetalpetal adalah kerangka kerja pemrosesan gambar berdasarkan logam yang dirancang untuk menyediakan pemrosesan waktu nyata untuk gambar dan video diam dengan antarmuka pemrograman yang mudah digunakan.
Bab ini mencakup konsep -konsep utama Metalpetal, dan akan membantu Anda mendapatkan pemahaman yang lebih baik tentang desain, implementasinya, implikasi kinerja, dan praktik terbaik.
Metalpetal dirancang dengan tujuan berikut dalam pikiran.
API yang mudah digunakan
Memberikan API kenyamanan dan menghindari jebakan umum.
Pertunjukan
Gunakan CPU, GPU, dan memori secara efisien.
Kemungkinan diperpanjang
Mudah membuat filter khusus serta plugin unit pemrosesan gambar khusus Anda.
Swifty
Memberikan pengalaman cairan untuk programmer cepat.
Beberapa konsep inti metalpetal sangat mirip dengan yang ada dalam kerangka gambar inti Apple.
Memberikan konteks evaluasi untuk memberikan MTIImage s. Ini juga menyimpan banyak cache dan informasi menyatakan, jadi lebih efisien untuk menggunakan kembali konteks bila memungkinkan.
Objek MTIImage adalah representasi dari suatu gambar yang akan diproses atau diproduksi. Ini secara langsung mewakili data bitmap gambar sebagai gantinya memiliki semua informasi yang diperlukan untuk menghasilkan gambar atau lebih tepatnya MTLTexture . Ini terdiri dari dua bagian, resep tentang cara menghasilkan tekstur ( MTIImagePromise ) dan informasi lain seperti bagaimana sebuah konteks cache gambar ( cachePolicy ), dan bagaimana tekstur harus disampel ( samplerDescriptor ).
MTIFilter mewakili efek pemrosesan gambar dan parameter apa pun yang mengontrol efek itu. Ini menghasilkan objek MTIImage sebagai output. Untuk menggunakan filter, Anda membuat objek filter, mengatur gambar dan parameter inputnya, dan kemudian mengakses gambar outputnya. Biasanya, kelas filter memiliki kernel statis ( MTIKernel ), ketika Anda mengakses properti outputImage , ia meminta kernel dengan gambar input dan parameter untuk menghasilkan MTIImage output.
MTIKernel mewakili rutinitas pemrosesan gambar. MTIKernel bertanggung jawab untuk membuat render atau menghitung keadaan pipa yang sesuai untuk filter, serta membangun MTIImagePromise untuk MTIImage .
Metalpetal melakukan banyak optimisasi untuk Anda di bawah kap.
Secara otomatis melemahkan fungsi, status kernel, status sampler, dll.
Ini menggunakan fitur logam seperti pencampuran yang dapat diprogram, target render tanpa memori, tumpukan sumber daya dan shader kinerja logam untuk membuat rendernya cepat dan efisien. Pada macOS, Metalpetal juga dapat memanfaatkan arsitektur TBDR Apple Silicon.
Sebelum rendering, Metalpetal dapat melihat ke grafik render gambar Anda dan mencari tahu jumlah minimal tekstur perantara yang diperlukan untuk melakukan rendering, menghemat memori, energi, dan waktu.
Ini juga dapat mengatur ulang grafik render gambar jika beberapa "resep" dapat digabungkan untuk menghilangkan lulus render yang berlebihan. ( MTIContext.isRenderGraphOptimizationEnabled )
Objek MTIImage tidak dapat diubah, yang berarti mereka dapat dibagikan dengan aman di antara utas.
Namun, objek MTIFilter dapat berubah dan karenanya tidak dapat dibagikan dengan aman di antara utas.
MTIContext berisi banyak negara bagian dan cache. Ada mekanisme yang aman untuk objek MTIContext , membuatnya aman untuk berbagi objek MTIContext di antara utas.
Fungsi verteks dan fragmen yang sepenuhnya dapat disesuaikan.
Dukungan MRT (beberapa target render).
Secara umum kinerja yang lebih baik. (Data benchmark terperinci diperlukan)
Matriks warna
Pencarian warna
Menggunakan tabel pencarian warna untuk memetakan warna pada gambar.
Kegelapan
Paparan
Kejenuhan
Kecerahan
Kontras
Color Invert
Getaran
Menyesuaikan saturasi gambar sambil menjaga warna kulit yang menyenangkan.
Kurva nada RGB
Mode campuran
Blend dengan topeng
Mengubah
Tanaman
Pixellate
Komposit multilayer
Konvolusi anggota parlemen
MPS Gaussian Blur
Definisi anggota parlemen
Sobel anggota parlemen
Topeng unsharp anggota parlemen
Kotak MPS Blur
Perataan kulit lulus tinggi
CLAHE (Kesetaraan Histogram Adaptif Terbatas Kontras)
Lensa Blur (Hexagonal Bokeh Blur)
Permukaan blur
Distorsi tonjolan
Campuran Kunci Chroma
Warna setengah btone
Layar dot
Sudut bulat (kurva melingkar/kontinu)
Semua filter gambar inti
MTIImage Anda dapat membuat objek MTIImage dari hampir semua sumber data gambar, termasuk:
URL S Referensi file gambar yang akan dimuatCVImageBufferRef atau CVPixelBufferRef )CIImage gambar intiMDLTexture 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 Jika Anda ingin memindahkan proses pengkodean perintah GPU keluar dari utas utama, Anda dapat menggunakan MTIThreadSafeImageView . Anda dapat menetapkan MTIImage ke MTIThreadSafeImageView di utas apa pun.
Metalpetal memiliki tipe API yang aman untuk menghubungkan filter. Anda dapat menggunakan => operator di Fungsi FilterGraph.makeImage untuk menghubungkan filter dan mendapatkan gambar output.
Berikut beberapa contoh:
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
} Anda dapat menghubungkan filter unary ( MTIUnaryFilter ) secara langsung menggunakan => .
Untuk filter dengan beberapa input, Anda harus terhubung ke salah satu inputPorts .
=> Operator hanya berfungsi dalam metode FilterGraph.makeImage .
Satu dan hanya satu output filter yang dapat dihubungkan ke output .
Bekerja dengan 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 ( )Ekspor video:
Videoo diperlukan untuk contoh -contoh berikut.
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
} )Videoo diperlukan untuk contoh ini.
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
} Silakan merujuk ke CameraFilterView.swift dalam proyek contoh untuk lebih lanjut tentang pratinjau dan perekaman video langsung yang difilter.
Gunakan kembali MTIContext jika memungkinkan.
Konteks adalah objek kelas berat, jadi jika Anda membuatnya, lakukan sedini mungkin, dan menggunakannya kembali setiap kali Anda perlu membuat gambar.
Gunakan MTIImage.cachePolicy dengan bijak.
Gunakan MTIImageCachePolicyTransient ketika Anda tidak ingin mempertahankan hasil render dari suatu gambar, misalnya ketika gambar hanyalah hasil perantara dalam rantai filter, sehingga tekstur yang mendasari hasil render dapat digunakan kembali. Ini adalah opsi paling efisien memori. Namun, ketika Anda meminta konteks untuk membuat gambar yang diberikan sebelumnya, itu dapat membuat ulang gambar itu karena tekstur yang mendasarinya telah digunakan kembali.
Secara default, gambar output filter memiliki kebijakan transient .
Gunakan MTIImageCachePolicyPersistent saat Anda ingin mencegah tekstur yang mendasarinya digunakan kembali.
Secara default, gambar yang dibuat dari sumber eksternal memiliki kebijakan persistent .
Pahami bahwa MTIFilter.outputImage adalah properti komputasi.
Setiap kali Anda meminta filter untuk gambar outputnya, filter dapat memberi Anda objek gambar output baru bahkan jika input identik dengan panggilan sebelumnya. Jadi gunakan kembali gambar output bila memungkinkan.
Misalnya,
// ╭→ filterB
// filterA ─┤
// ╰→ filterC
//
// filterB and filterC use filterA's output as their input.Dalam situasi ini, solusi berikut:
let filterOutputImage = filterA . outputImage
filterB . inputImage = filterOutputImage
filterC . inputImage = filterOutputImagelebih baik dari:
filterB . inputImage = filterA . outputImage
filterC . inputImage = filterA . outputImage Jika Anda ingin menyertakan MTIShaderLib.h ke dalam file .metal Anda, Anda perlu menambahkan jalur file MTIShaderLib.h ke Metal Compiler - Header Search Paths ( MTL_HEADER_SEARCH_PATHS ) pengaturan.
Misalnya, jika Anda menggunakan cocoapod, Anda dapat mengatur MTL_HEADER_SEARCH_PATHS ke ${PODS_CONFIGURATION_BUILD_DIR}/MetalPetal/MetalPetal.framework/Headers atau ${PODS_ROOT}/MetalPetal/Frameworks/MetalPetal/Shaders . Jika Anda menggunakan Swift Package Manager, atur MTL_HEADER_SEARCH_PATHS ke $(HEADER_SEARCH_PATHS)
Metalpetal memiliki mekanisme bawaan untuk menyandikan argumen fungsi shader untuk Anda. Anda dapat meneruskan argumen fungsi shader sebagai name: value kamus ke MTIRenderPipelineKernel.apply(toInputImages:parameters:outputDescriptors:) , MTIRenderCommand(kernel:geometry:images:parameters:) , dll.
Misalnya, kamus parameter untuk fungsi logam vibranceAdjust bisa:
// 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 ) ]])
{
...
}
Jenis argumen fungsi shader dan jenis yang sesuai untuk digunakan dalam kamus parameter tercantum di bawah ini.
| Jenis Argumen Fungsi Shader | Cepat | Objektif-C |
|---|---|---|
| mengambang | Mengambang | mengambang |
| int | Int32 | int |
| uint | Uint32 | uint |
| bool | Bool | bool |
| SIMD (float2, float4, float4x4, int4, dll.) | SIMD (dengan MetalPetal/Swift ) / Mtivector | Mtivector |
| struct | Data / mtidatabuffer | Nsdata / mtidatabuffer |
| Lainnya (float *, struct *, dll.) Immutable | Data / mtidatabuffer | Nsdata / mtidatabuffer |
| Lainnya (float *, struct *, dll.) Diubah | Mtidatabuffer | Mtidatabuffer |
Untuk membangun filter unary khusus, Anda dapat mensublasir MTIUnaryImageRenderingFilter dan mengganti metode dalam kategori SubclassingHooks . Contoh: MTIPixellateFilter , MTIVibranceFilter , MTIUnpremultiplyAlphaFilter , MTIPremultiplyAlphaFilter , dll.
// 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 ) )
}
} Untuk membangun filter yang lebih kompleks, yang perlu Anda lakukan adalah membuat kernel ( MTIRenderPipelineKernel / MTIComputePipelineKernel / MTIMPSKernel ), kemudian menerapkan kernel ke gambar input. Contoh: MTIChromaKeyBlendFilter , MTIBlendWithMaskFilter , MTIColorLookupFilter , dll.
@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 Anda dapat menggunakan MTIRenderCommand untuk mengeluarkan beberapa panggilan undian di One Render Pass.
// 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 ] )Anda juga dapat membuat beberapa deskriptor output untuk mengeluarkan banyak gambar dalam satu render pass (MRT, lihat https://en.wikipedia.org/wiki/multiple_render_targets).
Ketika MTIVertex tidak dapat sesuai dengan kebutuhan Anda, Anda dapat mengimplementasikan protokol MTIGeometry untuk memberikan data verteks khusus Anda ke encoder perintah.
Gunakan API MTIRenderCommand untuk mengeluarkan panggilan menarik dan lulus MTIGeometry khusus Anda.
Dalam skenario langka, Anda mungkin ingin mengakses tekstur yang mendasarinya secara langsung, menggunakan beberapa anggota parlemen dalam satu render pass, melakukan rendering 3D, atau menyandikan perintah render sendiri.
Protokol MTIImagePromise menyediakan akses langsung ke tekstur yang mendasarinya dan konteks render untuk langkah dalam metalpetal.
Anda dapat membuat sumber input baru atau unit pemrosesan khusus sepenuhnya dengan mengimplementasikan protokol MTIImagePromise . Anda perlu mengimpor modul tambahan untuk melakukannya.
Objektif-C
@import MetalPetal.Extension;
Cepat
// CocoaPods
import MetalPetal.Extension
// Swift Package Manager
import MetalPetalObjectiveC.Extension
Lihat implementasi MTIComputePipelineKernel , MTICLAHELUTRecipe atau MTIImage misalnya.
Jika saluran alfa digunakan dalam suatu gambar, ada dua representasi umum yang tersedia: alpha yang tidak ditentukan (lurus/tidak terkait), dan alpha premultiplied (terkait).
Dengan alpha yang tidak bermanfaat, komponen RGB mewakili warna piksel, mengabaikan opacity -nya.
Dengan alpha premultiplied, komponen RGB mewakili warna piksel, disesuaikan dengan opacity dengan perkalian.
Metalpetal menangani tipe alpha secara eksplisit. Anda bertanggung jawab untuk menyediakan tipe alpha yang benar selama pembuatan gambar.
Ada tiga jenis alfa di Metalpetal.
MTIAlphaType.nonPremultiplied : Nilai alfa dalam gambar tidak praultiplied.
MTIAlphaType.premultiplied : Nilai alfa dalam gambar adalah premultiplied.
MTIAlphaType.alphaIsOne : Tidak ada saluran alfa pada gambar atau gambarnya buram.
Biasanya, objek CGImage , CVPixelBuffer dan CIImage memiliki saluran alpha premultiplied. MTIAlphaType.alphaIsOne sangat disarankan jika gambarnya buram, misalnya CVPixelBuffer dari umpan kamera, atau CGImage yang dimuat dari file jpg .
Anda dapat menghubungi unpremultiplyingAlpha() atau premultiplyingAlpha() pada MTIImage untuk mengonversi jenis alfa dari gambar.
Untuk alasan kinerja, validasi tipe alpha hanya terjadi di Debug Build.
Sebagian besar filter di Metalpetal menerima gambar alfa dan buram dan output gambar alfa yang tidak ditentukan.
Filter dengan properti outputAlphaType menerima input dari semua jenis alpha. Dan Anda dapat menggunakan outputAlphaType untuk menentukan jenis alpha dari gambar output.
MTIBlendFilter MTIMultilayerCompositingFilter MTICoreImageUnaryFilter MTIRGBColorSpaceConversionFilter
Filter yang tidak benar -benar memodifikasi warna memiliki aturan penanganan alpha passthrough, itu berarti jenis alpha dari gambar output adalah sama dengan gambar input.
misalnya MTITransformFilter , MTICropFilter , MTIPixellateFilter , MTIBulgeDistortionFilter
Untuk informasi lebih lanjut tentang tipe alpha dan komposit alfa, silakan merujuk ke artikel interaktif yang luar biasa ini oleh Bartosz Ciechanowski.
Ruang warna sangat penting untuk pemrosesan gambar. Nilai numerik komponen merah, hijau, dan biru tidak memiliki arti tanpa ruang warna.
Sebelum melanjutkan bagaimana Metalpetal menangani ruang warna, Anda mungkin ingin tahu apa itu ruang warna dan bagaimana pengaruhnya terhadap representasi nilai warna. Ada banyak artikel di web yang menjelaskan ruang warna, untuk memulai, sarannya adalah ruang warna - oleh Bartosz Ciechanowski.
Perangkat lunak dan kerangka kerja yang berbeda memiliki cara menangani ruang warna yang berbeda. Misalnya, Photoshop memiliki ruang warna SRGB IEC61966-2.1 default, sedangkan gambar inti, secara default, menggunakan ruang warna kerja SRGB linier.
Tekstur logam tidak menyimpan informasi ruang warna dengan mereka. Sebagian besar penanganan ruang warna di metalpetal terjadi selama input ( MTIImage(...) ) dan output ( MTIContext.render... ) dari data gambar.
Menentukan ruang warna untuk input berarti bahwa Metalpetal harus mengonversi nilai warna sumber ke ruang warna yang ditentukan selama pembuatan tekstur.
Saat memuat dari URL atau CGImage , Anda dapat menentukan ruang warna mana yang Anda inginkan dalam data tekstur, menggunakan MTICGImageLoadingOptions . Jika Anda tidak menentukan opsi apa pun saat memuat gambar, ruang warna RGB perangkat digunakan ( MTICGImageLoadingOptions.default ). Ruang warna nil menonaktifkan pencocokan warna, ini setara dengan menggunakan ruang warna gambar input untuk membuat MTICGImageLoadingOptions . Jika model ruang warna yang ditentukan bukan RGB, ruang warna RGB perangkat digunakan sebagai fallback.
Saat memuat dari CIImage , Anda dapat menentukan ruang warna mana yang Anda inginkan dari data tekstur, menggunakan MTICIImageRenderingOptions . Jika Anda tidak menentukan opsi apa pun saat memuat CIImage , ruang warna RGB perangkat digunakan ( MTICIImageRenderingOptions.default ). Ruang warna nil menonaktifkan pencocokan warna, nilai warna dimuat dalam ruang warna CIContext .
Saat menentukan ruang warna untuk output, ruang warna lebih seperti tag yang digunakan untuk berkomunikasi dengan sisa sistem tentang cara mewakili nilai warna dalam output. Tidak ada konversi ruang warna yang sebenarnya dilakukan.
Anda dapat menentukan ruang warna dari output CGImage menggunakan MTIContext.makeCGImage... atau MTIContext.startTaskTo... metode dengan parameter colorSpace .
Anda dapat menentukan ruang warna output CIImage menggunakan MTICIImageCreationOptions .
Metalpetal mengasumsikan bahwa nilai warna output ada di ruang warna RGB saat tidak ada ruang warna output yang ditentukan.
CVPixelBuffer Metalpetal menggunakan CVMetalTextureCache dan IOSurface untuk secara langsung memetakan CVPixelBuffer s ke tekstur logam. Jadi, Anda tidak dapat menentukan ruang warna untuk memuat dari atau rendering ke CVPixelBuffer . Namun Anda dapat menentukan apakah akan menggunakan tekstur dengan format piksel SRGB untuk pemetaan.
Dalam logam, jika nama format piksel memiliki akhiran _sRGB , maka kompresi gamma SRGB dan dekompresi diterapkan selama membaca dan menulis nilai warna dalam piksel. Itu berarti tekstur dengan format piksel _sRGB mengasumsikan nilai warna yang disimpannya adalah SRGB gamma yang dikoreksi, ketika nilai warna dibaca dalam konversi RGB SRGB ke linier dilakukan. Ketika nilai warna ditulis dalam shader, konversi RGB ke SRGB linier dilakukan.
Anda dapat menggunakan MTIRGBColorSpaceConversionFilter untuk melakukan konversi ruang warna. Fungsi konversi ruang warna juga tersedia di MTIShaderLib.h .
metalpetal::sRGBToLinear (SRGB IEC61966-2.1 ke SRGB linear)metalpetal::linearToSRGB (linear SRGB ke SRGB IEC61966-2.1)metalpetal::linearToITUR709 (linier srgb ke ITU-R 709)metalpetal::ITUR709ToLinear (ITU-R 709 ke SRGB linier) Anda dapat menggunakan MTISCNSceneRenderer untuk menghasilkan MTIImage s dari SCNScene . Anda mungkin ingin menangani ruang warna RGB linier scenekit renderer, lihat masalah #76 gambar dari scenekit lebih gelap dari biasanya.
Anda dapat menggunakan MTISKSceneRenderer untuk menghasilkan MTIImage s dari SKScene .
Anda dapat membuat MTIImage s dari CIImage s.
Anda dapat membuat MTIImage ke CIImage menggunakan MTIContext .
Anda dapat menggunakan CIFilter secara langsung dengan MTICoreImageKernel atau kelas MTICoreImageUnaryFilter . (Hanya cepat)
Lihat Metalpetaljs
Dengan Metalpetaljs Anda dapat membuat pipa render dan filter menggunakan JavaScript, sehingga memungkinkan untuk mengunduh filter/renderer Anda dari "Cloud".
Dianjurkan agar Anda menggunakan API yang menerima MTICGImageLoadingOptions untuk memuat CGImage dan gambar dari URL , alih -alih menggunakan API yang menerima MTKTextureLoaderOption .
Saat Anda menggunakan API yang menerima MTKTextureLoaderOption , Metalpetal, secara default, menggunakan MTIDefaultTextureLoader untuk memuat CGImage S, gambar dari URL , dan gambar yang disebutkan. MTIDefaultTextureLoader menggunakan MTKTextureLoader secara internal dan memiliki beberapa solusi untuk inkonsistensi dan bug MTKTextureLoader dan bug dengan biaya kinerja yang kecil. Anda juga dapat membuat loader tekstur Anda sendiri dengan mengimplementasikan protokol MTITextureLoader . Kemudian tetapkan kelas Loader Tekstur Anda ke MTIContextOptions.textureLoaderClass saat membuat MTIContext .
Anda dapat menggunakan Cocoapods untuk menginstal versi terbaru.
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'
SwiftMemberikan penambahan dan modifikasi khusus cepat pada API Objective-C untuk meningkatkan pemetaan mereka menjadi Swift. Sangat disarankan jika Anda menggunakan Swift.
AppleSiliconMemberikan pustaka shader default yang dikompilasi dalam bahasa shading logam v2.3 yang diperlukan untuk memungkinkan dukungan pencampuran yang dapat diprogram pada Mac silikon apel.
Menambahkan dependensi paket ke aplikasi Anda
Metalpetal dapat berjalan pada simulator dengan Xcode 11+ dan MacOS 10.15+.
MetalPerformanceShaders.framework tidak tersedia di simulator, jadi filter yang mengandalkan MetalPerformanceShaders , seperti MTIMPSGaussianBlurFilter , MTICLAHEFilter , tidak berfungsi.
Simulator mendukung lebih sedikit fitur atau batas implementasi yang berbeda dari GPU Apple yang sebenarnya. Lihat Mengembangkan Aplikasi Logam yang Berlari Dalam Simulator Untuk Detail.
Jika Anda melakukan tampilan cepat pada MTIImage , itu akan menunjukkan kepada Anda grafik gambar yang Anda buat untuk menghasilkan gambar itu.

Mengapa Objective-C?
Terima kasih telah mempertimbangkan berkontribusi pada Metalpetal. Baca pedoman yang berkontribusi kami.
Metalpetal dilisensikan MIT. LISENSI
File -file dalam direktori /MetalPetalExamples dilisensikan dengan lisensi terpisah. Lisensi.md
Dokumentasi berlisensi CC-by-4.0.