溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么使用Flutter+Metal實現圖像處理

發布時間:2022-06-18 13:54:29 來源:億速云 閱讀:202 作者:iii 欄目:開發技術

這篇“怎么使用Flutter+Metal實現圖像處理”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“怎么使用Flutter+Metal實現圖像處理”文章吧。

基本思路

Flutter使用CVPixelBuffer和iOS交互,我們可以直接使用CVPixelBuffer創建MTLTexture,然后將MTLTexture設置為渲染目標。這樣Metal框架可以直接將渲染結果寫入CVPixelBuffer,達到更加高效的目的。

Metal環境設置

主要初始化Device,PipelineState,CommandQueue三個對象。我們需要依賴Device分配各種Metal資源,PipelineState管理著渲染流水線的各個環節的配置,比如vertex shader,fragment shader,輸出像素格式等。CommandQueue用于管理執行的繪制命令。

_device = MTLCreateSystemDefaultDevice();
id<MTLLibrary> lib = [_device newDefaultLibrary];
id<MTLFunction> vertexFunc = [lib newFunctionWithName:vertexFuncName];
id<MTLFunction> fragFunc = [lib newFunctionWithName:fragFuncName];
MTLRenderPipelineDescriptor *renderPipelineDesc = [MTLRenderPipelineDescriptor new];
renderPipelineDesc.vertexFunction = vertexFunc;
renderPipelineDesc.fragmentFunction = fragFunc;
renderPipelineDesc.colorAttachments[0].pixelFormat = MTLPixelFormatBGRA8Unorm;
_pipelineState = [_device newRenderPipelineStateWithDescriptor:renderPipelineDesc error:nil];
_commandQueue = [_device newCommandQueue];

從CVPixelBuffer創建MTLTexture紋理

首先創建一個CVPixelBuffer對象

NSDictionary *pixelAttributes = @{( id )kCVPixelBufferIOSurfacePropertiesKey : @{}};
CVPixelBufferCreate(
            kCFAllocatorDefault,
                    imageWidth,
                    imageHeight,
            kCVPixelFormatType_32BGRA,
                    (__bridge CFDictionaryRef)pixelAttributes,
                    &_renderTargetPixelBuffer);

利用CVMetalTextureCacheCreateTextureFromImageCVPixelBuffer創建MTLTexture

CVReturn ret = CVMetalTextureCacheCreate(kCFAllocatorDefault, nil, _mtContext.device, nil, &_textureCache);
CVMetalTextureRef renderTargetMetalTextureRef;
ret = CVMetalTextureCacheCreateTextureFromImage(kCFAllocatorDefault, _textureCache, _renderTargetPixelBuffer, nil, MTLPixelFormatBGRA8Unorm, imageWidth, imageHeight, 0, &renderTargetMetalTextureRef);
id<MTLTexture> mtlTexture = CVMetalTextureGetTexture(renderTargetMetalTextureRef);

渲染到紋理

CommandQueue獲得一個CommandBuffer,用于保存需要執行的繪制命令

_activeCmdBuffer = [_commandQueue commandBuffer];

創建MTLRenderPassDescriptor設置本次繪制的相關配置,比如繪制到哪里,這里指定通過CVPixelBuffer創建出來的MTLTexture,是否清除當前內容,清除的顏色

MTLRenderPassDescriptor *renderPassDesc = [MTLRenderPassDescriptor new];
renderPassDesc.colorAttachments[0].texture = target;
renderPassDesc.colorAttachments[0].loadAction = MTLLoadActionClear;
renderPassDesc.colorAttachments[0].clearColor = MTLClearColorMake(0, 0, 0, 1);

通過CommandBufferMTLRenderPassDescriptor創建一個MTLRenderCommandEncoder

_activeEncoder = [_activeCmdBuffer renderCommandEncoderWithDescriptor:renderPassDesc];

指定MTLRenderCommandEncoder所在的PipelineState

[_activeEncoder setRenderPipelineState:_pipelineState];

使用MTLRenderCommandEncoder綁定BufferTexture,在Metal里,Uniform和Vertex Buffer 都是通過MTLBuffer綁定到Shader中

[_activeEncoder setVertexBuffer:vertexBuffer offset:0 atIndex:0];
[_activeEncoder setFragmentBuffer:uniformBuffer offset:0 atIndex:0];
[_activeEncoder setFragmentBuffer:texture offset:0 atIndex:0];

繪制圖形

[_activeEncoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:vertexCount instanceCount:1];

顯式的結束MTLRenderCommandEncoder

[_activeEncoder endEncoding];

提交CommandBuffer

[_activeCmdBuffer commit];

等待繪制結束,如果你想要異步等待,需要在[_activeCmdBuffer commit]之前設置completedHandler

// 同步等待
[_activeCmdBuffer waitUntilCompleted];
// 異步等待
[_activeCmdBuffer addCompletedHandler:^(id<MTLCommandBuffer> _Nonnull buf) {
}];

到此繪制的內容就已經在CVPixelBuffer中了,再將CVPixelBuffer提交給Flutter顯示即可

以上就是關于“怎么使用Flutter+Metal實現圖像處理”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女