iOS:从网址加载图片

时间:2012-06-10 21:38:04

标签: ios uiimageview uiimage nsurl

我需要从url加载图像并将其设置在UIImageView中;问题是我不知道图像的确切大小,那么如何才能正确显示图像呢?

9 个答案:

答案 0 :(得分:112)

只需使用UIImage的size属性,例如:

NSURL *url = [NSURL URLWithString:path];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *img = [[UIImage alloc] initWithData:data];
CGSize size = img.size;

答案 1 :(得分:13)

在swift:

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

答案 2 :(得分:9)

快速使用期权:

var url:NSURL? = NSURL(string: imageString)
var data:NSData? = NSData(contentsOfURL : url!)
var image = UIImage(data : data!)

答案 3 :(得分:6)

  

IN 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()
}

}

答案 4 :(得分:1)

要使用Kingfisher库下载异步图像,您可以按照以下步骤操作,网址为: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
                       }
                    }
                }
            }
        }
    }

答案 5 :(得分:0)

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)")
        }
    }
}

答案 6 :(得分:0)

显示从json或url下载的图像的一个常见错误是队列问题。所有与UI相关的事情都需要在主队列中完成,因此,如果您忘记了这一点,那么即使是完美的代码(上面的答案也不错)有时也不会显示您的图像。要调用mainQueue,请使用如下代码,并注意,调用主队列可能需要在被调用的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.
}

答案 7 :(得分:0)

快速安全代码版本:

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
    }
}

答案 8 :(得分:0)

如果您愿意,甚至可以将其移至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)
    }
    
}