Как конвертировать металлическую текстуру в PNG и обратно ⇐ IOS
-
Гость
Как конвертировать металлическую текстуру в PNG и обратно
Я пытаюсь преобразовать текстуру металла в данные png (или любой другой формат, сжатый без потерь), чтобы сохранить их на диск.
После преобразования данных обратно в текстуру я хочу получить ту же текстуру без изменений.
У меня это работает с непрозрачными текстурами, но с прозрачными пикселями что-то идет не так.
Это код, который я использую для сжатия и распаковки текстуры.
public struct TextureCompresser { пусть контекст:CIContext пусть загрузчик: MTKTextureLoader общественный инициализации (устройство: MTLDevice) { загрузчик = MTKTextureLoader (устройство: устройство) контекст = CIContext(опции: [ CIContextOption.outputPremultiplied: ложь, ]) } общественная функция сжатия (текстура: MTLTexture) -> Данные? { let options:[CIImageOption:Any] = [CIImageOption.colorSpace:CGColorSpace(имя: CGColorSpace.linearSRGB)!] Guard let ciImage = CIImage(mtlTexture: текстура, параметры: параметры) еще {возвратить ноль} return context.pngRepresentation(of: ciImage, формат: .BGRA8, colorSpace: CGColorSpace(имя: CGColorSpace.sRGB)!)!) } public func decompress(png:Data) throws -> MTLTexture { let using = MTLTextureUsage(rawValue: MTLTextureUsage.renderTarget.rawValue | MTLTextureUsage.shaderRead.rawValue | MTLTextureUsage.shaderWrite.rawValue) пусть параметры: [MTKTextureLoader.Option: Любой] = [ MTKTextureLoader.Option.textureUsage:usage.rawValue, MTKTextureLoader.Option.origin:MTKTextureLoader.Origin.flippedVertically.rawValue, MTKTextureLoader.Option.SRGB:NSNumber(значение: true), MTKTextureLoader.Option.generateMipmaps:NSNumber(значение: false), ] вернуть попытку loader.newTexture(данные: png, параметры: параметры) } } Я поместил этот код в репозиторий здесь.
Обратите внимание, что я использую линейное цветовое пространство для параметров CIImage. Мне это кажется неправильным, поскольку мои текстуры имеют формат sRGB, но это был единственный способ заставить его работать вообще (но только для непрозрачных пикселей). Мои текстуры — bgra8Unorm_srgb.
Хотя это работает с непрозрачными пикселями, прозрачные пиксели изменяются. Например, тестовый пиксель преобразуется после сжатия/распаковки следующим образом:
[24, 72, 233, 78] -> [48, 127, 255, 78]
Я перепробовал все возможные комбинации опций и цветовых пространств, которые только мог придумать, но ничего не помогло. Кто-нибудь знает, что я делаю не так?
Я пытаюсь преобразовать текстуру металла в данные png (или любой другой формат, сжатый без потерь), чтобы сохранить их на диск.
После преобразования данных обратно в текстуру я хочу получить ту же текстуру без изменений.
У меня это работает с непрозрачными текстурами, но с прозрачными пикселями что-то идет не так.
Это код, который я использую для сжатия и распаковки текстуры.
public struct TextureCompresser { пусть контекст:CIContext пусть загрузчик: MTKTextureLoader общественный инициализации (устройство: MTLDevice) { загрузчик = MTKTextureLoader (устройство: устройство) контекст = CIContext(опции: [ CIContextOption.outputPremultiplied: ложь, ]) } общественная функция сжатия (текстура: MTLTexture) -> Данные? { let options:[CIImageOption:Any] = [CIImageOption.colorSpace:CGColorSpace(имя: CGColorSpace.linearSRGB)!] Guard let ciImage = CIImage(mtlTexture: текстура, параметры: параметры) еще {возвратить ноль} return context.pngRepresentation(of: ciImage, формат: .BGRA8, colorSpace: CGColorSpace(имя: CGColorSpace.sRGB)!)!) } public func decompress(png:Data) throws -> MTLTexture { let using = MTLTextureUsage(rawValue: MTLTextureUsage.renderTarget.rawValue | MTLTextureUsage.shaderRead.rawValue | MTLTextureUsage.shaderWrite.rawValue) пусть параметры: [MTKTextureLoader.Option: Любой] = [ MTKTextureLoader.Option.textureUsage:usage.rawValue, MTKTextureLoader.Option.origin:MTKTextureLoader.Origin.flippedVertically.rawValue, MTKTextureLoader.Option.SRGB:NSNumber(значение: true), MTKTextureLoader.Option.generateMipmaps:NSNumber(значение: false), ] вернуть попытку loader.newTexture(данные: png, параметры: параметры) } } Я поместил этот код в репозиторий здесь.
Обратите внимание, что я использую линейное цветовое пространство для параметров CIImage. Мне это кажется неправильным, поскольку мои текстуры имеют формат sRGB, но это был единственный способ заставить его работать вообще (но только для непрозрачных пикселей). Мои текстуры — bgra8Unorm_srgb.
Хотя это работает с непрозрачными пикселями, прозрачные пиксели изменяются. Например, тестовый пиксель преобразуется после сжатия/распаковки следующим образом:
[24, 72, 233, 78] -> [48, 127, 255, 78]
Я перепробовал все возможные комбинации опций и цветовых пространств, которые только мог придумать, но ничего не помогло. Кто-нибудь знает, что я делаю не так?
Мобильная версия