iOS:从 url 加载图像
Posted
技术标签:
【中文标题】iOS:从 url 加载图像【英文标题】:iOS: load an image from url 【发布时间】:2012-06-13 21:53:58 【问题描述】:我需要从 url 加载图像并将其设置在 UIImageView 中;问题是我不知道图片的确切尺寸,那我该如何正确显示图片呢?
【问题讨论】:
为什么会有问题?下载图像后,您将知道其大小。您还可以将图像视图设置为您想要的大小并拉伸图像以适合。 【参考方案1】:只需使用 UIImage 的 size 属性即可,例如:
NSURL *url = [NSURL URLWithString:path];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *img = [[UIImage alloc] initWithData:data];
CGSize size = img.size;
【讨论】:
或者在图像视图上设置您想要的大小,然后在下载后拉伸图像以适合图像视图。 (你应该伸展并保持纵横比,其他一切看起来都很奇怪) 啊好的...但我不明白如何为我的 imageView 调整此图像的大小;我应该创建一个缩影,我的 imageView 没有太多空间(最大 236 宽度和最大 60 高度);在这个空间中,我应该从 url 加载图像,但它应该是成比例的...... 我想你想要的是将 UIImageView 的 contentMode 设置为 UIContentViewScaleAspectFit。但是请查看文档。 感谢此代码。我有一个问题,如何在检索图片时显示“正在加载”并在图片下载失败时通知? @Shannon 你得到答案了吗?【参考方案2】:迅速:
var url = NSURL.URLWithString("http://www.example.com/picture.png")
var data = NSData(contentsOfURL : url)
var image = UIImage(data : data)
image.size // if you need it
【讨论】:
【参考方案3】:关于使用选项的快速说明:
var url:NSURL? = NSURL(string: imageString)
var data:NSData? = NSData(contentsOfURL : url!)
var image = UIImage(data : data!)
【讨论】:
如果图像文件不在指定的图像字符串中,这将崩溃。 利用 if let 语句!这是不安全的代码,如果 url 为 nil 会崩溃【参考方案4】:在 SWIFT 3.0 中
主线程必须始终保持空闲,以便为用户界面和用户交互提供服务。
class ViewController: UIViewController
@IBOutlet weak var imageView: UIImageView!
private func fetchImage()
let imageURL = URL(string: "https://i.stack.imgur.com/9z6nS.png")
var image: UIImage?
if let url = imageURL
//All network operations has to run on different thread(not on main thread).
DispatchQueue.global(qos: .userInitiated).async
let imageData = NSData(contentsOf: url)
//All UI operations has to run on main thread.
DispatchQueue.main.async
if imageData != nil
image = UIImage(data: imageData as! Data)
self.imageView.image = image
self.imageView.sizeToFit()
else
image = nil
override func viewDidLoad()
super.viewDidLoad()
fetchImage()
【讨论】:
【参考方案5】:要下载Kingfisher库的异步图像,你可以按照这个步骤,url:https://github.com/onevcat/Kingfisher:
func imageFromUrl(_ urlString: String)
if let url = URL(string: urlString)
ImageDownloader.default.downloadImage(with: url, options: [], progressBlock: nil)
(image, error, url, data) in
DispatchQueue.main.async
self.imageView.image = image
您也可以使用默认 URLSession.shared.dataTask 下载图片
func imageFromUrl(_ urlString: String)
if let url = URL(string: urlString)
let request = URLRequest(url: url)
URLSession.shared.dataTask(with: request) (data,response,error) in
if let imageData = data as Data?
if let img = UIImage(data: imageData)
DispatchQueue.main.async
self.imageView.image = img
【讨论】:
【参考方案6】:SWIFT 5.0 + 后台获取
private func fetchImage(_ photoURL: URL?)
guard let imageURL = photoURL else return
DispatchQueue.global(qos: .userInitiated).async
do
let imageData: Data = try Data(contentsOf: imageURL)
DispatchQueue.main.async
let image = UIImage(data: imageData)
self.userImageView.image = image
self.userImageView.sizeToFit()
self.tableView.reloadData()
catch
print("Unable to load data: \(error)")
【讨论】:
【参考方案7】:显示从 json 或 url 下载的图像的一个常见错误是队列问题。所有与 UI 相关的事情都需要在 主队列 中完成,因此如果您忘记了这一点,即使是完美的代码(以上答案都很好)有时也不会显示您的图像。要调用 mainQueue,使用这样的代码,并注意调用 main queue 可能需要在被调用的 imageDisplay 函数中单独完成:
dispatch_async(dispatch_get_main_queue(), ^
self.nameLabel.text = self.pokemon.name;
[self displayImage]; //CALLS FUNCTION
self.abilitiesTextView.text = @"loves SwiftUI";
);
- (void)displayImage
NSString *imageURLString = [NSString stringWithFormat: self.pokemon.sprite];
NSData *imageData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:imageURLString]];
dispatch_async(dispatch_get_main_queue(), ^
self.spriteImageView.image = [UIImage imageWithData: imageData];
);
// NOTE: important for newer versions of XCode/Obj-C...
//[imageData release]; With ARC ("automated release..."), release method is forbidden, it's already done for you.
【讨论】:
【参考方案8】:如果您愿意,甚至可以将其移至 UIImage
扩展名:
extension UIImage
//NOTE: This is not thread safe, please run it on a background thread.
convenience init?(fromFile filePath:String)
guard let url = URL(string: filePath) else
return nil
self.init(fromURL: url)
//NOTE: This is not thread safe, please run it on a background thread.
convenience init?(fromURL url:URL)
let imageData: Data
do
imageData = try Data(contentsOf: url)
catch
return nil
self.init(data: imageData)
【讨论】:
【参考方案9】:Swift 安全代码版本:
private func loadImage(from url:URL) -> UIImage?
let imageData: Data
do
imageData = try Data(contentsOf: url)
catch
return nil
return UIImage(data: imageData)
private func loadImage(from urlString:String) -> UIImage?
guard let url = URL(string: urlString) else
return nil
return self.loadImage(from: url)
请记住,此代码会阻塞主线程,因此您应该在后台线程上运行它。例如:
DispatchQueue.global().async
let image = UIImage(fromFile: "http://xpto.com/image.png")
// And then you should update UI on main thread.
// If you have an UIImageView outlet you can update its image this way:
DispatchQueue.main.async
imageView.image = image
imageView.contentMode = .scaleAspectFit
【讨论】:
以上是关于iOS:从 url 加载图像的主要内容,如果未能解决你的问题,请参考以下文章
在幻灯片 iOS APP 中从 URL Xcode 9 加载图像
如何从从json获得的url加载图像到collectionview