将MTLTexture保存和加载为PNG

问题描述

我正在尝试将金属纹理保存并加载为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 (将#修改为@)