I am trying to convert WKImage to Data(NSData) but always getting nil.
let image = WKImage(imageName: "sample")
print("Image = \(image)")
let imageData = image.imageData
print("Image Data = \(imageData)")
Below is out put
Image = <WKImage: 0x7a66ff40>
Image Data = nil
If you are creating WKImage with init(imageName: String) constructor, only imageName parameter will not be nil. image and imageData parameters are not nil only when WKImage was created via init(image: UIImage) or init(imageData: Data) respectfully.
You can get this imageName, then create UIImage with it's init(named: String) constructor, and then convert this UIImage to data using UIImageJPEGRepresentation or UIImagePNGRepresentation functions:
UIImagePNGRepresentation(UIImage(named: image.imageName!)!)
Related
When the user selects an item from their photo library, the app saves the UIImage to the app's directory using the following code:
let imageUUID = UUID()
let filename = getDocumentsDirectory().appendingPathComponent("\(imageUUID)")
guard let uiImage = newImage else { return}
if let jpegData = uiImage.jpegData(compressionQuality: 0.8) {
try? jpegData.write(to: filename, options: [.atomicWrite, .completeFileProtection])
}
How can I use the saved image in a view?
Thanks!
First, you should save the UUID somewhere so that you can read the file later. This could be in UserDefaults, a JSON file, CoreData, or whatever, depending on your needs.
Suppose you have the path to the file stored in filePath, you can create an Image like this:
Image(uiImage: UIImage(contentsOfFile: filePath) ?? UIImage())
This will use an empty image as fallback if it failed to read the file.
Following code convert UIImage to Image in SwiftUI:
let uiImage = UIImage(contentsOfFile: path) ?? UIImage() // Access it from your storage
let image = Image(uiImage: uiImage)
There are different UIImage initializer methods available, you can use any one of them to get UIImage instance.
https://developer.apple.com/documentation/swiftui/image
You will like this tutorial of Coredata with SwiftUI: https://www.raywenderlich.com/9335365-core-data-with-swiftui-tutorial-getting-started
I'm trying to retrieve and visualize an image from postgres to iOS, and I tried turning into Data and then UIImage but with no luck, when i create the UIImage it returns nil.
As you can see from the image below, I get that string from the db, with double backslash and x, that should be normal, I tried both to keep the escaping symbols and to trim them, I also tried to initialize the Data with both initializer with byte: and base64Encoded, with and without options but the image is always nil.
screenshot from xcode
func dataToImage(data:String)->Image{
var imageData = Data(bytes: "68747470733a2f2f73332e65752d63656e7472616c2d312e616d617a6f6e6177732e636f6d2f696c6172696f73616c6174696e6f2f31423236303332462d363935422d344342432d393733412d3342413936343841334535372d373136312d303030303145323833464643303541442e6a706567", count: data.count)
var base64data = Data(base64Encoded: "68747470733a2f2f73332e65752d63656e7472616c2d312e616d617a6f6e6177732e636f6d2f696c6172696f73616c6174696e6f2f31423236303332462d363935422d344342432d393733412d3342413936343841334535372d373136312d303030303145323833464643303541442e6a706567", options: .ignoreUnknownCharacters)
return Image(uiImage: UIImage(data: imageData)!)
}
the string I get from the db:
data String "\\x68747470733a2f2f73332e65752d63656e7472616c2d312e616d617a6f6e6177732e636f6d2f696c6172696f73616c6174696e6f2f31423236303332462d363935422d344342432d393733412d3342413936343841334535372d373136312d303030303145323833464643303541442e6a706567"
Any help appreciated, thanks!
You are not saving image data correctly =/
To get UIImage Data properly you should:
let data = yourImage.jpegData(compressionQuality: 1)
It will return an Data
So, save it like a String and its ready!
To set image from Data its like these:
let data = Data(base64Encoded: myString)
let newImage = UIImage(data: data)
To debug more easily use this string to convert to Data and Image. This string provides us a Data and an Image properly
"/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCABAAEADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD3+iiopp1gALg4PcUJXAloqut7A/Rqk+0Rf38fUYp2YrklFRfaIi2A2foM0vnR5wXAPoeKLMdySikDK3RgfoaWkAVma0+y1B9606x/EJIskx13VUdxPYp2zl1GVyParjvkx43KWUAnjPU+tZdr9zkVad9ph7jaOD9TWjJMnTNS+26C15qFqLuWCeZNkEIZmKsF+Vc9cGtJdetreFUOm6pFGP8ApxchRn2z61z+kmKOwmD25lA1S8C44x84rpYZBPHH5R8lyf4o2fPt1GKTVwFk1jTBLLE9ysTxOY2M0bRru54DMAG6djWxZ824+p/nWJHeyeV5cqyZxyy4x+RY1s6ec2i5OTk8n60pbDW5arE8SNi1jA/vf4Vt15/8TfFcPhlNOWW0kuftRfAjmEZXbg55Bz1pU4uUrLcJSUVeWxp2eMYLLj2rQKwtGjPjgAZ3ds14sPi3aRNkaHcH63i//E1KPjVAoH/EknGP+nxP/iK39hU7fkZqtTfU9A8P+W+m3LhA6nUrtlB/3x61src7GVvs06KByFjU5/EGvMvD3jS4/sTTYbTSDc3F891c4a8SMIPO28krz0qw3izWJHQroSfOQqn+04iOTjqU4qOR/wBNF8y/pM9GW4jIKrbThevEWB/OtrSz/omB2YivH4/GmqRoZ/7GhKDg/wDE1hHP/fI/WvRfAWvjxFoEt59m+zMly8LxecsuCoH8S8d6mUXa/wCqGpK9jdl02GYcy3S/7lzIv8mrJvvBOh6p5f8AaVu995efL+1yGUpnGcFs46CuhorNSa2HZHI/8Kx8H/8AQDtP+/K/4Up+GXg8qQdDtMEY4iUfyFdbRT55dwsjlE+G3hJLaG2/saCSGAMIll+fYGYsQC2SOSTTh8N/Bw/5l6wP1hFdTRRzS7hZHNL8PfCC/wDMu6cfrAprY03SNP0aBoNNs4rWFm3GOJdq59cdKu0UnJvdhZH/2Q=="
I hope it helped you!
Cheers
try this
class ImageConverter {
func base64ToImage(_ base64String: String) -> UIImage? {
guard let imageData = Data(base64Encoded: base64String) else { return nil }
return UIImage(data: imageData)
}
func imageToBase64(_ image: UIImage) -> String? {
return image.jpegData(compressionQuality: 1)?.base64EncodedString()
}
}
I have a UIImage variable, a. I would like to use it within my app as a .png data file. How do I go about recasting a back into a UIImage for use?
How can I cast this data object back into a UIImage?
let pngImage = a!.pngData()
Converting UIImage to PNG Data:
extension UIImage {
// UIImage to Data (PNG Representation)
var PNGData: Data? {
return UIImagePNGRepresentation(self)
}
}
Using your example:
let a = UIImage("foo") // Sample image named foo
UIImage to Data:
let pngData = a.data
Data to UIImage:
let pngImage = UIImage(data: pngData)
I need to convert the image to/from Base64.
All working fine for JPG files, but if I upload PNG and then open it in the app it leads to the crash with error
"Unexpectedly found nil while unwrapping an Optional value"
while trying to create Data from the encoded string
Here is my code:
For Encoding:
static func base64Convert(base64String: String?) -> UIImage {
var decodedImage = #imageLiteral(resourceName: "no_prof_image")
if ((base64String?.isEmpty)! || (base64String?.contains("null"))!) {
return decodedImage
}else {
if let imageBase64String = base64String,
let dataDecoded = Data(base64Encoded: imageBase64String, options: .ignoreUnknownCharacters) {
decodedImage = UIImage(data: dataDecoded) ?? #imageLiteral(resourceName: "no_prof_image")
}
return decodedImage
}
}
For Decoding:
static func makeProfileBase64FromImage(image: UIImage) -> String? {
var imageData : Data?
if let jpegData = UIImageJPEGRepresentation(image, 1.0) {
imageData = jpegData
} else if let pngData = UIImagePNGRepresentation(image) {
imageData = pngData
}
return imageData?.base64EncodedString()
}
What I tried:
1) All encoding options
2) All decoding options
3) Swap UIImageJPEGRepresentation to UIImagePNGRepresentation. It leads to the same error but with jpg images.
UPDATE
Here is code how I send data to the server:
var imageToSend : String = "null"
if profileImage.image != #imageLiteral(resourceName: "no_prof_image"),
let validImage = profileImage.image,
let imageBase64 = AppUtils.makeProfileBase64FromImage(image: validImage) {
imageToSend = imageBase64
}
let parameters : Parameters = [
"image": imageToSend
]
Alamofire.request(AppUtils.API_URL + "update_profile.php", method: .post, parameters: parameters)
.validate().responseData() {response in
switch response.result {
case .success:
//...Some stuff
break
case .failure:
//...Some stuff
break
}
}
Part of the string that came to the server:
/9j/4AAQSkZJRgABAQAASABIAAD/4QBYRXhpZgAATU0AKgAAAAgAAgESAAMAAAABAAEAAIdpAAQAAAABAAAAJgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAABkKADAAQAAAABAAABkAAAAAD/7QA4UGhvdG9zaG9wIDMuMAA4QklNBAQAAAAAAAA4QklNBCUAAAAAABDUHYzZjwCyBOmACZjs+EJ+/8AAEQgBkAGQAwERAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/EAB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//E
UPDATED CODE IN THE QUESTION
For now, the code doesn't have force unwrap. But now I always gets standard #imageLiteral(resourceName: "no_prof_image"). (Before, at least jpg works fine :) )
Quite obviously, you use UIImageJPEGRepresentation for .jpeg images, but for .png images you should use UIImagePNGRepresentation
Also, don't use force unwrapping.
static func makeBase64FromImage(image: UIImage) -> String? {
var imageData : Data?
if let jpegData = UIImageJPEGRepresentation(image, 1.0) {
imageData = jpegData
} else if let pngData = UIImagePNGRepresentation(image) {
imageData = pngData
}
return imageData?.base64EncodedString()
}
Looks like your issue is your PNG data size which is much bigger than JPEG data. So your server might have a size limit for your image upload.
Regarding your encoding method The second condition else if let pngData = UIImagePNGRepresentation(image) will never be executed. You have to choose which one you would like to use PNG or JPEG data representations (JPEG most times due to the size limit). Btw this would be much easier using optional chaining.
return UIImageJPEGRepresentation(image, 1)?.base64EncodedString()
Swift 4.2 Xcode 10 or later
return image.jpegData(compressionQuality: 1)?.base64EncodedString()
As #mag_zbc suggested, start with:
static func makeBase64FromImage(image: UIImage) -> String? {
var imageData : Data?
if let jpegData = UIImageJPEGRepresentation(image, 1.0) {
imageData = jpegData
} else if let pngData = UIImagePNGRepresentation(image) {
imageData = pngData
}
return imageData?.base64EncodedString()
}
Then, update this code to:
var imageToSend : String = "null"
if profileImage.image != #imageLiteral(resourceName: "no_prof_image"),
let validImage = profileImage.image,
let imageBase64 = AppUtils.makeBase64FromImage(image: validImage) {
imageToSend = imageBase64
}
let parameters : Parameters = [
"image": imageToSend
]
...
In general, you want to avoid using "!" anywhere unless you can 100% confirm that in any and all cases the value will always be defined. In this case, I believe the issue was your code being called with profileImage.image == nil
A profileImage.image being nil would != to the image literal, and therefore would have entered the conditional if you defined. Then by forcing it to be unwrapped with "!" you tried to unwrap nil.
Good luck!
I am using CoreData for an app. I have set image as BinaryData in data model. But I have fetched image from server as UIImage and it throws error as:
cannot assign value of type 'UIImage?' to type 'NSData?
I searched but couldn't find any resemblance solution for it. Can anyone help me in swift 3?
My code is:
let url1:URL = URL(string:self.appDictionary.value(forKey: "image") as! String)!
let picture = "http://54.243.11.100/storage/images/news/f/"
let strInterval = String(format:"%#%#",picture as CVarArg,url1 as CVarArg) as String as String
let url = URL(string: strInterval as String)
SDWebImageManager.shared().downloadImage(with: url, options: [],progress: nil, completed: {[weak self] (image, error, cached, finished, url) in
if self != nil {
task.imagenews = image //Error:cannot assign value of type 'UIImage?' to type 'NSData?'
}
})
The error message is pretty clear - you cannot assign UIImage object to a variable of NSData type.
To convert UIImage to Swift's Data type, use UIImagePNGRepresentation
var data : Data = UIImagePNGRepresentation(image)
Note that if you're using Swift, you should be using Swift's type Data instead of NSData
You must convert, image into Data (or NSData) to support imagenews data type.
Try this
let url1:URL = URL(string:self.appDictionary.value(forKey: "image") as! String)!
let picture = "http://54.243.11.100/storage/images/news/f/"
let strInterval = String(format:"%#%#",picture as CVarArg,url1 as CVarArg) as String as String
let url = URL(string: strInterval as String)
SDWebImageManager.shared().downloadImage(with: url, options: [],progress: nil, completed: {[weak self] (image, error, cached, finished, url) in
if self != nil {
if let data = img.pngRepresentationData { // If image type is PNG
task.imagenews = data
} else if let data = img.jpegRepresentationData { // If image type is JPG/JPEG
task.imagenews = data
}
}
})
// UIImage extension, helps to convert Image into data
extension UIImage {
var pngRepresentationData: Data? {
return UIImagePNGRepresentation(img)
}
var jpegRepresentationData: Data? {
return UIImageJPEGRepresentation(self, 1.0)
}
}