macos - 相当于 MacOS 10.13 之前的 MPSImageLanczosScale
问题描述
我正在使用框架MPSImageLanczosScale
来缩放图像纹理(从 开始CVPixelBufferRef
) 。Metal
该问题MPSImageLanczosScale
仅从 10.13 开始可用。但我的应用程序从 10.11 开始支持。我不能停止支持较低的操作系统版本,因为仍然有很多用户使用这些版本。有没有其他方法可以使用 Metal(或使用任何其他方式)缩放图像?
注意:我使用的是 Metal,因为我需要基于 GPU 的图像缩放以避免任何 CPU 消耗。所以我正在寻找基于 GPU 的图像缩放解决方案。
包括当前的实现供您参考。
-(CVImageBufferRef)rescaleGPU:(CVImageBufferRef)sourceImageBuffer {
CVReturn error;
CGFloat backingScaleFactor = [[NSScreen mainScreen] backingScaleFactor];
CVMetalTextureRef textureRef;
error = CVMetalTextureCacheCreateTextureFromImage(kCFAllocatorDefault, _videoTextureCache, sourceImageBuffer, NULL, MTLPixelFormatBGRA8Unorm, g_screenWidth * backingScaleFactor, g_screenHeight * backingScaleFactor, 0, &textureRef);
id <MTLTexture> _metalTexture = CVMetalTextureGetTexture(textureRef);
id<MTLTexture> _destinationTexture = [_device newTextureWithDescriptor:self.textureDescriptor];
id<MTLCommandBuffer> commandBuffer = [_commandQueue commandBuffer];
[self.scaleFilter encodeToCommandBuffer:commandBuffer sourceTexture:_metalTexture destinationTexture:_destinationTexture];
id<MTLBlitCommandEncoder> blitEncoder = [commandBuffer blitCommandEncoder];
[blitEncoder synchronizeTexture:_destinationTexture slice:0 level:0];
[blitEncoder endEncoding];
[commandBuffer commit];
[commandBuffer waitUntilCompleted];
void* destData = malloc(scaleHeight * scaleWidth * 4);
[_destinationTexture getBytes:destData bytesPerRow:scaleWidth * 4 fromRegion:self.destinationRegion mipmapLevel:0];
CVPixelBufferCreateWithBytes(kCFAllocatorDefault, scaleWidth, scaleHeight, kCVPixelFormatType_32BGRA, destData, scaleWidth * 4, NULL, NULL, NULL, &finalBuffer);
CVBufferRelease(textureRef);
[_destinationTexture release];
free(destData);
return finalBuffer;
}
解决方案
对于没有MPSImageLanczosScale
. _ 它的质量会降低,但您不必自行调整大小,也不必放弃未更新其操作系统的现有用户。
使scaleFilter
您的班级成员成为类型MPSImageScale*
if (@available(macOS 10.13, *))
{
self.scaleFilter = [[MPSImageLanczosScale alloc] initWithDevice:device];
}
else
{
self.scaleFilter = [[MPSImageBilinearScale alloc] initWithDevice:device];
}
它们具有相同的基本接口MPSUnaryImageKernel
,因此您不必更改代码的其他部分,至少据我所知。
推荐阅读
- rollupjs - 汇总缩小类名
- rabbitmq - RabbitMQ 调度消息和撤销功能
- sql - 在日期范围之间递归输入月份年份名称
- django - 单独常量文件中的 Django 模型选择
- tensorflow - 在 Tensorboard 中查看来自 Keras Tuner 的日志
- python - 如何删除前导和尾随下划线,但不删除两个单词之间的下划线?
- angular - 带有故事书 6 的 Angular 8
- java - MultipartUploadRequest(上传时出错)android 10
- php - 额外的添加到购物车按钮重定向到 WooCommerce Loop 上的结帐
- swift - 如何使 backBarButton 在模态演示中工作?