【问题标题】:Use a remote image for MTKTextureLoader为 MTKTextureLoader 使用远程图像
【发布时间】:2020-07-12 15:17:28
【问题描述】:

我正在尝试使用以下代码从 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,但无法让它按原样工作,而且我还不够了解如何更新它。

【问题讨论】:

  • 这能回答你的问题吗? Load a remote image using MTKTextureLoader
  • @warrenm 遗憾的是,没有。我找到了一个,但它不能开箱即用,而且我还不够精明,无法弄清楚如何更新它。

标签: swift metal metalkit


【解决方案1】:

这是MTKTextureLoader(与 Swift 5 兼容)的扩展,它从远程 URL 下载图像并从中创建金属纹理。它遵循与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()
    }
}

请注意,如果您的应用是沙盒化的,则应在您的权利中启用“传出连接”(如果您尚未启用)。

此外,混合下载、缓存和纹理加载等问题并不是最佳做法,因此如果您要加载大量远程文件,我建议将其重构为更通用的远程资源缓存系统。这仅用于演示目的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-09-08
    • 1970-01-01
    • 2020-02-11
    • 2019-06-13
    • 1970-01-01
    • 2016-12-29
    • 1970-01-01
    • 2019-03-07
    相关资源
    最近更新 更多