为 MTKTextureLoader 使用远程图像
Use a remote image for MTKTextureLoader
我正在尝试使用以下代码从 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 让它工作。有人对此有任何好运吗?
我试过 但无法让它按原样工作,而且我的知识还不够了解如何更新它。
这是 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()
}
}
请注意,如果您的应用是沙盒应用,您应该在您的授权中启用 "Outgoing Connections"(如果您尚未启用)。
此外,混合下载、缓存和纹理加载等问题并不是最佳做法,因此如果您要加载大量远程文件,我建议将其重构为更通用的远程资源缓存系统。这仅用于演示目的。
我正在尝试使用以下代码从 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 让它工作。有人对此有任何好运吗?
我试过
这是 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()
}
}
请注意,如果您的应用是沙盒应用,您应该在您的授权中启用 "Outgoing Connections"(如果您尚未启用)。
此外,混合下载、缓存和纹理加载等问题并不是最佳做法,因此如果您要加载大量远程文件,我建议将其重构为更通用的远程资源缓存系统。这仅用于演示目的。