问题描述
我正在尝试将金属纹理保存并加载为PNG,但是当我将它们重新加载时,它们会显得模糊。我认为问题在于,转换800x600的纹理会创建1600x1200的PNG,因此我必须缩小PNG的尺寸,才能将其加载到正确大小的MTLTexture中。
这是我的将纹理转换为PNG数据的代码:
func textureToImage(texture: MTLTexture) -> Data {
let kciOptions: [CIImageOption:Any] = [.colorSpace: CGColorSpaceCreateDeviceRGB()]
let ciImage = CIImage(mtlTexture: texture,options: kciOptions)!
let transform = CGAffineTransform.identity
.scaledBy(x: 1,y: -1)
.translatedBy(x: 0,y: ciImage.extent.height)
let transformed = ciImage.transformed(by: transform)
return UIImage(ciImage: transformed).pngData()!
}
有关2x缩放问题的示例:
let texture: MTLTexture = ...
texture.width // => 800
let image = textureToImage(texture)
image.size.width // => 800
let data = image.pngData()!
let reloadedImage = UIImage(data: data)!
reloadedImage.size.width // => 1600
因此,当将纹理转换为图像时,CIImage似乎将分辨率提高了一倍。这是我将其转换回去的代码,我认为缩小尺寸会导致模糊:
func load(_ image: UIImage) -> MTLTexture {
// The image is twice the texture resolution so we have to scale it down
let scaled = scale(image: image,scale: 0.5)
let options: [MTKTextureLoader.Option: Any] = [
.SRGB: false,.generateMipmaps: true,.textureUsage: MTLTextureUsage.unknown.rawValue
]
let loader = MTKTextureLoader(device: Renderer.device)
let texture = try! loader.newTexture(cgImage: scaled,options: options)
return texture.makeTextureView(pixelFormat: .bgra8Unorm)!
}
func scale(image: UIImage,scale: Float) -> CGImage {
let scale = CGFloat(scale)
let newWidth = image.size.width * scale
let newHeight = image.size.height * scale
UIGraphicsBeginImageContext(CGSize(width: newWidth,height: newHeight))
image.draw(in: CGRect(x: 0,y: 0,width: newWidth,height: newHeight))
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage!.cgImage!
}
有没有一种方法可以将UIImage加载回MTLTexture中而不必按比例缩小?或者,是否有一种方法可以避免将CIImage转换为图像时将其分辨率提高一倍?我需要将纹理存储为PNG,因为它们有很多,并且它们吞噬了太多的内存作为原始纹理数据。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)