Сохранение и загрузка MTLTexture в формате PNGIOS

Программируем под IOS
Anonymous
Сохранение и загрузка MTLTexture в формате PNG

Сообщение Anonymous »

Я пытаюсь сохранить и загрузить металлические текстуры в формате PNG, но когда я загружаю их обратно, они кажутся более размытыми. Я думаю, проблема в том, что при преобразовании текстуры размером 800x600 создается PNG размером 1600x1200, поэтому мне приходится уменьшать масштаб 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()!
}
Для примера проблемы 2-кратного масштабирования:

Код: Выделить всё

  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, потому что у меня их много, и они занимают слишком много памяти в виде необработанных данных текстур.


Подробнее здесь: https://stackoverflow.com/questions/639 ... ure-as-png

Вернуться в «IOS»