我有一个 UIImage 我之前从 png 文件创建的:
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
似乎没有奏效。我错过了什么吗?
任何指针将不胜感激。