【问题标题】:Equivalent of MPSImageLanczosScale before MacOS 10.13相当于 MacOS 10.13 之前的 MPSImageLanczosScale
【发布时间】:2021-05-02 10:58:03
【问题描述】:

我正在使用MPSImageLanczosScale 使用Metal 框架来缩放图像纹理(从CVPixelBufferRef 开始)。问题是 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;
}

【问题讨论】:

    标签: macos metal image-scaling cvpixelbuffer


    【解决方案1】:

    对于使用没有MPSImageLanczosScale 的版本的用户,您可以回退到MPSImageBilinearScale。它的质量会降低,但您不必自行调整大小,也不必放弃未更新其操作系统的现有用户。

    使您班级的scaleFilter 成员的类型为MPSImageScale*

    if (@available(macOS 10.13, *))
    {
        self.scaleFilter = [[MPSImageLanczosScale alloc] initWithDevice:device];
    }
    else 
    {
        self.scaleFilter = [[MPSImageBilinearScale alloc] initWithDevice:device];
    }
    

    它们具有相同的基本接口MPSUnaryImageKernel,因此您不必更改代码的其他部分,至少据我所知。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-09-24
      • 2018-03-17
      • 1970-01-01
      • 1970-01-01
      • 2018-03-14
      • 2021-10-31
      • 2018-03-06
      • 2020-04-24
      相关资源
      最近更新 更多