Я использую MPSImageLanczosScale
для масштабирования текстуры изображения (инициированной из CVPixelBufferRef
) с использованием Metal
framework. Проблема в том, что MPSImageLanczosScale
доступен только с 10.13. Но мое приложение поддерживает с 10.11. Я не могу перестать поддерживать более ранние версии ОС, так как многие пользователи все еще используют эти версии. Есть ли альтернативный способ масштабирования изображения с помощью Metal (или любым другим способом)?
Примечание. Я использую Metal, так как мне нужно масштабирование изображения на основе графического процессора, чтобы избежать использования процессора. Поэтому я ищу решение для масштабирования изображения на основе графического процессора.
Включая текущую реализацию для справки.
-(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;
}