let image: UIImage = UIImage(named:"imageView")!
let imageData: NSData = UIImagePNGRepresentation(image)! as NSData
base64String = imageData.base64EncodedString(options: .lineLength64Characters)
print(base64String as Any)
My problem is the variable (image) is null, but I'm sure I have selected the correct imageView
Your code will only work if the image exists in your asset catalog and the asset catalog is member of your target.
Maybe you just added the file to your project and not to the asset catalog? In this case try
guard let url = Bundle.main.url(forResource: "image", withExtension: "jpg") else {
return
}
guard let data = try? Data(contentsOf: url) else {
return
}
print(data.base64EncodedString())
Related
im using the below code to load a downloaded image from disk, when the file exists I can load it as image. If it doesn't image returns as nil.
How could I modify the code to replace return nil with loading a placeholder image from my asset folder called default.png. So instead of returning nil, there is always an image return, either downloaded one that's trying to load or if it doesn't exist, my own asset image.
func loadImageFromDiskWith(fileName: String) -> UIImage? {
let documentDirectory = FileManager.SearchPathDirectory.documentDirectory
let userDomainMask = FileManager.SearchPathDomainMask.userDomainMask
let paths = NSSearchPathForDirectoriesInDomains(documentDirectory, userDomainMask, true)
if let dirPath = paths.first {
let imageUrl = URL(fileURLWithPath: dirPath).appendingPathComponent(fileName)
let image = UIImage(contentsOfFile: imageUrl.path)
return image
}
return nil
}
You can do as below -
func loadImageFromDiskWith(fileName: String) -> UIImage {
let documentDirectory = FileManager.SearchPathDirectory.documentDirectory
let userDomainMask = FileManager.SearchPathDomainMask.userDomainMask
let paths = NSSearchPathForDirectoriesInDomains(documentDirectory, userDomainMask, true)
var image = UIImage(named: "default") // Make sure there must be "default.png" in your main bundle.
if let dirPath = paths.first {
let imageUrl = URL(fileURLWithPath: dirPath).appendingPathComponent(fileName)
if FileManager.default.fileExists(atPath: imageUrl.path) { //Check here for file existence. It won't crash.
image = UIImage(contentsOfFile: imageUrl.path)
}
}
return image
}
my issue is when I try to encode an image to base-64, it generate a long string (up to 200,000 lines) and it doesn't work in the decoding, it generate a nil image! even I try to resize the image to a smaller size but still it doesn't work!
Here is my image encoding code
let image = imageView.image
let imageData:NSData = UIImagePNGRepresentation(image!)! as NSData
let strBase64 = imageData.base64EncodedString(options: .lineLength64Characters)
The decoding code:
let processImage = user.value(forKey: "processImage") as! String // image from json
if let dataDecoded:NSData = NSData(base64Encoded: processImage, options: NSData.Base64DecodingOptions.ignoreUnknownCharacters) {
let image: UIImage = UIImage(data:dataDecoded as Data,scale:1.0)!
print(image.size)
self.myImage.image = image }
You can try Following Steps:
Step :- 1 First Fetch the NSData from it
There are three Possibilities:
1. Using Image Name
let image : UIImage = UIImage(named:"imageNameHere")!
//Now use image to create into NSData format
let imageData:NSData = UIImagePNGRepresentation(image)!
2. Using NSURL:
//Use image's path to create NSData
let url:NSURL = NSURL(string : "urlHere")!
//Now use image to create into NSData format
let imageData:NSData = NSData.init(contentsOfURL: url)!
3. Image picked from image picker
let image = info[UIImagePickerControllerOriginalImage] as? UIImage
let imageData:NSData = UIImagePNGRepresentation(image)!
Step:-2 Then Encode:
let strBase64 = imageData.base64EncodedString(options: .lineLength64Characters)
print(strBase64)
Step:-3 Then Decode:
let dataDecoded : Data = Data(base64Encoded: strBase64, options: .ignoreUnknownCharacters)!
let decodedimage = UIImage(data: dataDecoded)
yourImageView.image = decodedimage
Hope it helps.
I have an array of URLs linking to image files, how do I store them into an array of UIImages?
var imagesArray = [UIImage]()
let links = ["http://example.com/image1.jpg","http://example.com/image2.jpg"] as [String]
There must be an easy solution.
If it was one image I could do something like the following:
let url = URL(string: link2image!)!
let imageData = try? Data(contentsOf: url)
let image = UIImage(data: imageData!)!
self.image.append(image)
The easiest solution would be to just iterate through the array and download the images synchronously using Data(contentsOf:), however, this would be quite insufficient due to synchronous execution.
let images = links.flatMap{ link->UIImage? in
guard let url = URL(string: link) else {return nil}
guard let imageData = try? Data(contentsOf: url) else {return nil}
return UIImage(data: imageData)
}
A better solution would be to download the images asynchronously in parallel, I have written a UIImage extension for this using PromiseKit:
extension UIImage {
class func downloadedAsync(fromUrl url: URL)->Promise<UIImage> {
return Promise{ fulfill, reject in
URLSession.shared.dataTask(with: url, completionHandler: { data, response, error in
guard let data = data, error == nil else {
reject(error!); return
}
guard let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 else {
reject(NSError(domain: "Wrong HTTP response code when downloading image asynchronously",code: (response as? HTTPURLResponse)?.statusCode ?? 1000));return
}
guard let mimeType = response?.mimeType, mimeType.hasPrefix("image"), let image = UIImage(data: data) else {
reject(NSError(domain: "No image in response", code: 700)); return
}
fulfill(image)
}).resume()
}
}
}
You call it for an array of links like this:
var imageDownloadTasks = links.flatMap{ link in
guard let url = URL(string: link) else {return nil}
return UIImage.downloadedAsync(fromUrl: url)
}
Then execute the promises:
when(fulfilled: imageDownloadTasks).then{ images in
//use the images, images is of type [UIImage]
}
Maybe you can try Functional programming use: map closure ...
links.map({
if let imageData = try? Data(contentsOf: URL(string: $0)!) {
UIImage(data: imageData)
}
})
But you must know if your links is wrong, it will crash. So, I suggest you make some guard to prevent these crashes. like this...
guard let url = URL(string: $0) else { return nil }
I have a plist running in my project which contains number of image urls.I am trying to pass the url image to my imageView which is in the same viewController.I found similar questions from github like Loading/Downloading image from URL on Swift , Swift - Read plist , Can't get plist URL in Swift I went through all those answers but no luck so far rather than fatal crash. My partial codes as follows....
Method 1:
override func viewDidLoad() {
super.viewDidLoad()
if let path = Bundle.main.path(forResource: "apps", ofType: "plist"),
let root = (NSArray(contentsOfFile: path))
{
let url = NSURL(string: path)
let data = NSData(contentsOf: url! as URL)
if let imageData = data {
imageView.image = UIImage(data: imageData as Data)
}
**// Swift Console Printinging as Follows**
print(root)
// printing all my plist url links like {icon = "https://xxxxxxxxxxx.com/image/girl_face_freckles_eyes_92358_1920x1080.jpg";}
print(url)
// (/Users/xxxxxx/Library/Developer/CoreSimulator/Devices/52DA3F73-83E0-4C29-9DE1-D8D5F0731C13/data/Containers/Bundle/Applica ... ps.plist)
print(data)
// nil
print(imageView.image)
//nil
} else {
print("Either the file does not exist or the root object is an array")
}
Method 2:
let path = Bundle.main.path(forResource: "apps", ofType: "plist")
let url = NSURL(string: path!)
let imgData = try? Data(contentsOf: url as! URL)
let img = UIImage(data: imgData!)!
print(img) // fatal crash
}
path is the path to your plist, not to your image URL.
The image URL is in the key "icon" in the "root" array.
Get the first item of the array and subscript with the key, you should get your image URL:
if let item = root[0] as? [String:Any] {
if let result = item["icon"] as? String {
print(result)
}
}
The path in (NS)Bundle is a file system path and these paths must be created with URL(fileURLWithPath:)
let path = Bundle.main.path(forResource: "apps", ofType: "plist")
let url = URL(fileURLWithPath: path!)
But why does nobody use the URL related API which is much more convenient
let url = Bundle.main.url(forResource: "apps", withExtension: "plist")
I am new to swift.
I have one code. It encode a local image logo.png to NSData.
let testImage = NSData(contentsOfFile: NSBundle.mainBundle().pathForResource("logo", ofType: "png")!)
How to encode an image from a URL to NSData?
Replace myURL with the required URL:
let testImage = NSData(contentsOfURL: myURL)
Try this one :-
var image: UIImage?
let imgURL = NSURL(string: "\(yourURL)")
let request: NSURLRequest = NSURLRequest(URL: imgURL!)
let mainQueue = NSOperationQueue.mainQueue()
NSURLConnection.sendAsynchronousRequest(request, queue: mainQueue, completionHandler: { (response, data, error) -> Void in
if error == nil {
// Convert the downloaded data in to a UIImage object
image = UIImage(data: data!)
} else {
image = UIImage(named: "JobPlaceholder") // if occurred an error put a placeholder image
}
})
I have done in swift 3.3 and 4. But this will hang UI and result in jerk.
do {
let imgData = try NSData(contentsOf: URL.init(string: "SomeUrl")!, options: NSData.ReadingOptions())
let image = UIImage(data: imgData as Data)
DispatchQueue.main.async() { () -> Void in
completionBlock(image)
}
} catch {
}
You can also pass image url to dataTask method of URLSession and get data in response. This is best way to avoid jerk in UI. Like below
if let url = URL(string: "someUrl") {
URLSession.shared.dataTask(with: url) { (data, response, error) in
guard let httpURLResponse = response as? HTTPURLResponse, httpURLResponse.statusCode == 200,
let mimeType = response?.mimeType, mimeType.hasPrefix("image"),
let data = data, error == nil,
let image = UIImage(data: data) else {
DispatchQueue.main.async() { () -> Void in
completionBlock(nil)
}
return
}
DispatchQueue.main.async() { () -> Void in
completionBlock(image)
}
}.resume()
}
This one is working in Swift 3.0 Replace the contentsof:forcastURL with contentsOf: forecastURL! as URL
let forecastURL = NSURL(string: "http://photos.state.gov/libraries/media/788/images/90x90.gif")
let testImage = NSData (contentsOf: forecastURL! as URL)
print("data",testImage!)
let image = UIImage(data: testImage! as Data)
print("imaGE :-",image!)