Speichern und Laden von MTLTexture als PNGIOS

Programmierung für iOS
Anonymous
 Speichern und Laden von MTLTexture als PNG

Post by Anonymous »

Ich versuche, Metalltexturen als PNGs zu speichern und zu laden, aber wenn ich sie wieder lade, erscheinen sie unschärfer. Ich denke, das Problem besteht darin, dass beim Konvertieren einer Textur mit 800 x 600 ein PNG mit 1600 x 1200 entsteht. Daher muss ich das PNG herunterskalieren, um es in eine MTLTexture mit der richtigen Größe zu laden.
Hier ist mein Code zum Konvertieren einer Textur in PNG-Daten:

Code: Select all

  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()!
}
Ein Beispiel für das 2x-Skalierungsproblem:

Code: Select all

  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 scheint also die Auflösung zu verdoppeln, wenn die Textur in ein Bild konvertiert wird. Hier ist mein Code zum Zurückkonvertieren, wobei ich denke, dass die Verkleinerung zu Unschärfe führt:

Code: Select all

  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!
}
Gibt es für mich eine Möglichkeit, das UIImage wieder in eine MTLTexture zu laden, ohne es verkleinern zu müssen? Oder gibt es alternativ eine Möglichkeit zu vermeiden, dass CIImage die Auflösung der Textur verdoppelt, wenn sie in ein Bild konvertiert wird? Ich muss meine Texturen als PNGs speichern, weil ich viele davon habe und sie als rohe Texturdaten zu viel Speicher verbrauchen.

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post