Сохранение и загрузка 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
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

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