您好,登录后才能下订单哦!
这篇“怎么使用Flutter+Metal实现图像处理”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“怎么使用Flutter+Metal实现图像处理”文章吧。
Flutter使用CVPixelBuffer和iOS交互,我们可以直接使用CVPixelBuffer创建MTLTexture,然后将MTLTexture设置为渲染目标。这样Metal框架可以直接将渲染结果写入CVPixelBuffer,达到更加高效的目的。
主要初始化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对象
NSDictionary *pixelAttributes = @{( id )kCVPixelBufferIOSurfacePropertiesKey : @{}};
CVPixelBufferCreate(
            kCFAllocatorDefault,
                    imageWidth,
                    imageHeight,
            kCVPixelFormatType_32BGRA,
                    (__bridge CFDictionaryRef)pixelAttributes,
                    &_renderTargetPixelBuffer);利用CVMetalTextureCacheCreateTextureFromImage从CVPixelBuffer创建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);
CommandBuffer和MTLRenderPassDescriptor创建一个MTLRenderCommandEncoder_activeEncoder = [_activeCmdBuffer renderCommandEncoderWithDescriptor:renderPassDesc];
MTLRenderCommandEncoder所在的PipelineState[_activeEncoder setRenderPipelineState:_pipelineState];
MTLRenderCommandEncoder绑定Buffer和Texture,在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实现图像处理”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注亿速云行业资讯频道。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。