为MTKTextureLoader使用远程图像

问题描述 投票:-1回答:1

我正在尝试使用以下代码从URL加载纹理:

let textureLoader = MTKTextureLoader(device: device)
var texture: MTLTexture?
let origin = NSString(string: MTKTextureLoader.Origin.bottomLeft.rawValue)
let textureLoaderOptions = [MTKTextureLoader.Option.SRGB: 0, MTKTextureLoader.Option.origin: origin] as [MTKTextureLoader.Option: Any]

do {
   texture = try textureLoader.newTexture(URL: my-url-here, options: textureLoaderOptions)
} catch {
   print("texture not created")
}

当我从应用程序中加载纹理时,它工作正常,但似乎无法使用外部URL使其正常工作。有人有运气吗?

我尝试过Load a remote image using MTKTextureLoader,但无法使其按原样工作,而且我也不了解如何更新它。

swift metal metalkit
1个回答
0
投票

这里是MTKTextureLoader的扩展(与Swift 5兼容),它可以从远程URL下载图像并从中创建一个Metal纹理。它基本上遵循与existing asynchronous loading API相同的模式。

extension MTKTextureLoader {
    static let errorDomain = "com.example.MTKTextureLoader.RemoteExtensions"

    func newTexture(remoteURL url: URL, options: [MTKTextureLoader.Option : Any]? = nil, completionHandler: @escaping MTKTextureLoader.Callback) {
        let downloadTask = URLSession.shared.downloadTask(with: URLRequest(url: url)) { (maybeFileURL, maybeResponse, maybeError) in
            var anError: Swift.Error? = maybeError
            if let tempURL = maybeFileURL, let response = maybeResponse {
                if let cachePath = NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true).first {
                    let cachesURL = URL(fileURLWithPath: cachePath, isDirectory: true)
                    let cachedFileURL = cachesURL.appendingPathComponent(response.suggestedFilename ?? NSUUID().uuidString)
                    try? FileManager.default.moveItem(at: tempURL, to: cachedFileURL)
                    return self.newTexture(URL: cachedFileURL, options: options, completionHandler: completionHandler)
                } else {
                    anError = NSError(domain: MTKTextureLoader.errorDomain,
                                      code: 1,
                                      userInfo: [NSLocalizedDescriptionKey : "Unable to find user caches directory"])
                }
            } else {
                anError = NSError(domain: MTKTextureLoader.errorDomain,
                                  code: 2,
                                  userInfo: [NSLocalizedDescriptionKey : "Download from URL failed"])
            }
            completionHandler(nil, anError)
        }
        downloadTask.resume()
    }
}

请注意,如果您的应用已被沙箱化,则应该在权利中启用“传出连接”。

此外,将诸如下载,缓存和纹理加载之类的问题混为一谈也不是最佳实践,因此,如果要加载很多远程文件,我建议将其重构为更通用的远程资源缓存系统。这仅用于演示目的。

© www.soinside.com 2019 - 2024. All rights reserved.