【发布时间】:2019-05-16 08:53:32
【问题描述】:
我有一个之前从 png 文件创建的 UIImage:
let strokeUIImage = UIImage(data: pngData)
我想将 strokeImage(具有不透明度)转换为 MTLTexture 以在 MTKView 中显示,但进行转换似乎会执行不需要的预乘,这会使所有半透明边缘变暗。
我的混合设置如下:
pipelineDescriptor.colorAttachments[0].isBlendingEnabled = true
pipelineDescriptor.colorAttachments[0].rgbBlendOperation = .add
pipelineDescriptor.colorAttachments[0].alphaBlendOperation = .add
pipelineDescriptor.colorAttachments[0].sourceRGBBlendFactor = .one
pipelineDescriptor.colorAttachments[0].sourceAlphaBlendFactor = .one
pipelineDescriptor.colorAttachments[0].destinationRGBBlendFactor = .oneMinusSourceAlpha
pipelineDescriptor.colorAttachments[0].destinationAlphaBlendFactor = .oneMinusSourceAlpha
我尝试了两种转换方法:
let stampTexture = try! MTKTextureLoader(device: self.device!).newTexture(cgImage: strokeUIImage.cgImage!, options: nil)
还有更精细的dataProvider驱动的方法:
let image = strokeUIImage.cgImage!
let imageWidth = image.width
let imageHeight = image.height
let bytesPerPixel:Int! = 4
let rowBytes = imageWidth * bytesPerPixel
let texDescriptor = MTLTextureDescriptor.texture2DDescriptor(pixelFormat: .rgba8Unorm_srgb,
width: imageWidth,
height: imageHeight,
mipmapped: false)
guard let stampTexture = device!.makeTexture(descriptor: texDescriptor) else { return }
let srcData: CFData! = image.dataProvider?.data
let pixelData = CFDataGetBytePtr(srcData)
let region = MTLRegionMake2D(0, 0, imageWidth, imageHeight)
stampTexture.replace(region: region, mipmapLevel: 0, withBytes: pixelData!, bytesPerRow: Int(rowBytes))
两者都会产生相同的不想要的预乘结果。
我尝试了后者,因为有一些帖子表明旧的 swift3 方法 CGDataProviderCopyData() 从未预乘的图像中提取原始像素数据。可悲的是,相当于:
let srcData: CFData! = image.dataProvider?.data
似乎没有奏效。我错过了什么吗?
任何指针将不胜感激。
【问题讨论】:
-
您可以使用 Accelerate 函数(例如
vImageUnpremultiplyData_ARGB8888)从关联数据转到非关联数据,但如果您遇到相关问题,我建议您使用不同的混合模式使边缘变暗。如果您在整个管道中使用预乘颜色,则正确合成会容易得多。 -
谢谢,沃伦。我已更新问题以包含混合模式信息。我要做的就是将 png 数据合成到 MTKView 可绘制对象中。时期。但这样做似乎即使在一个空视图上也执行这种预乘,我不确定这是在哪里发生的。这似乎是一个遗留问题,因为很多帖子基本上都在问同样的问题,但我还没有看到明确的答案。我将如何使用您建议的加速功能?还有什么想法吗?提前致谢。
-
从 CoreGraphics 加载的所有图像都将预乘非不透明像素。我之前看过直接使用 libpng 加载,但问题很重要。
-
我在下面发布了一个答案,它让我完成了 95% 的工作......感谢 Warrenm 为我指明了 Accelerate 函数的方向
标签: swift png metal metalkit premultiplied-alpha