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 am trying to convert the Image selected from the UIImagePickerController into base64 String. But the length of the String is about more than 12 Corerit's making iPhone hang.
This is the code that I using.
func compressImage(img:UIImage) -> String {
Utill.showProgress()
var imageData = Data(UIImagePNGRepresentation(img)! )
print("***** Uncompressed Size \(imageData.description) **** ")
imageData = UIImageJPEGRepresentation(img, 0.025)!
print("***** Compressed Size \(imageData.description) **** ")
let image = UIImage(data: imageData)
let imagesData:NSData = UIImagePNGRepresentation(image!)! as NSData
let strBase64 = imagesData.base64EncodedString(options: .lineLength64Characters)
Utill.dismissProgress()
return strBase64
}
Is there any other way to reduce the String, to be around 10K - 30K?
Try this code,
func convertImageToBase64(image: UIImage)-> String {
if let imageData = image.jpegData(compressionQuality: 0.25){
let base64String = imageData.base64EncodedString()
return base64String
}
return ""
}
I have an array of images in my codes that are [UIImage] but I want to convert them to base64 - I couldn't ! - I found similar questions but when I used their answers I received Fatal Error
for i in 0...tinyViewController.imageUpload.count - 1 {
print(i)
let imageData = UIImageJPEGRepresentation(tinyViewController.imageUpload[i] , 1)
let base64String = (imageData! as Data).base64EncodedString(options: NSData.Base64EncodingOptions(rawValue: 0))
print(base64String)
}
Try this function to convert each UIImage to base64 String. I used it in my project. It works perfect for me.
func base64(from image: UIImage) -> String? {
let imageData = UIImagePNGRepresentation(image)
if let imageString = imageData?.base64EncodedString(options: .endLineWithLineFeed) {
return imageString
}
return nil
}
So, do this:
for i in 0...tinyViewController.imageUpload.count - 1 {
print(i)
print(base64(from: tinyViewController.imageUpload[i]))
}
I have a base64String that I need to convert into a UIImage() and display in a UIImageView. I've been trying for hours to convert it, but I keep getting nil from UIImage(data: data). When I print(data)it looks normal, but I can't decode it properly into an image. What's going on, and why is this code not working?
let base64String = "data:image/x-icon;base64,AAABAAEAEBAAAAAAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAAAAA2Gin/Nhop/zYaKf82Gin/Nhop/zYaKf82Gin/Nhop/zYaKf82Gin/Nhop/zYaKf82Gin/Nhop/zYaKf82Gin/Nhop/zYaKf88IjD/XUlU/2RRW/9GLzv/kouQ/6Sdn/84Hiz/RCs4/0QrOP82Gyn/Nhop/0UtOv9FLDr/OR8t/zYaKf85Hyz/ubO2////////////7+/v//////+6tbb/RS47/+bl5v/Py87/OR4s/0gxPf/z8/P/vrq8/1dFTv82Gin/a1xk//////+4s7f/hnuB//b29v/+/v7/SjdC/0EoNv/5+Pn/39zg/zgdK/9oWGD//////5OIjf9ELTn/Nhop/6CYnP//////X0xW/zYaKf/Cvb///////0czPv9AJzX/9vX2/+Dc3/86Hy7/lIqP//////9jUlr/OB0s/zYaKf+qpKb//////2ZSXf82Gin/zcbJ//////9RPkf/QCc1//X19f/c2Nv/Pyc0/8nGyP/8/Pz/RzA8/zYaKf82Gin/q6Wn//////9kUVv/Nhop/83Gyf//////UD1G/0AnNf/19fX/1NDT/0w4RP/5+fn/zcnL/zkfLf82Gin/Nhop/6ulp///////ZFFb/zYaKf/Nxsn//////1A9Rv9AJzX/8fDx//n4+f/U0NP//////6GYnP82Gin/Nhop/zYaKf+rpaf//////2RRW/82Gin/zcbJ//////9QPUb/QCc0//Dv7///////+vr6///////39vf/RzM//zYbKf82Gin/q6Wn//////9kUVv/Nhop/83Gyf//////UD1G/0AnNP/19PT/4N3e/0s0QP+HfIL//////5uRlv9HLzv/Nhop/6ylp///////ZFFb/zYaKf/Nxsn//////1A9Rv9AJzT/9fX1/9zZ2v85Hiz/VD9K//////+7tLf/VkJM/zYaKf+po6X//////2RRW/82Gin/xb3C//////9OPEX/QCc0//b19f/c2tr/OR4s/1I9SP//////t7Gz/1M/SP82Gin/joWJ//////98b3b/Ri47/9XS1P//////STI+/0MpNv/y8fH/6+np/3FfaP+poab//////46Dif9CKjf/Nhop/0c0P//39vf///////r6+///////pp+k/zYaKf9GLjr/8O/v//////////////////Dv7/9AKjb/Nhop/zYaKf82Gin/UkBJ/7Osrv/DvsD/joSJ/zkhLv82Gin/PCIw/35wdv+GeH7/hHd8/39yef9HMT3/Nhop/zYaKf82Gin/Nhop/zYaKf82Gin/Nhop/zYaKf82Gin/Nhop/zYaKf82Gin/Nhop/zYaKf82Gin/Nhop/zYaKf82Gin/AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//w="
let decodedData = NSData(base64EncodedString: base64String, options: NSDataBase64DecodingOptions.IgnoreUnknownCharacters)
print(decodedData) // prints out fine
let image = UIImage(data: decodedData!) // keep getting nil here
use this function for decode Base64 String to String
public func decodebase64(str : String) -> String{
let decodedData = NSData(base64EncodedString: str, options:NSDataBase64DecodingOptions(rawValue: 0))
let decodedString = String(data: decodedData!, encoding: NSUTF8StringEncoding)
return decodedString!}
then use this function in this way
let newimage:String? = decodebase64(busimage)
if (newimage?.characters.count != 0)
{
ImageLoader.sharedLoader.imageForUrl(newimage!) { (images, url) -> () in
if (images != nil)
{
cell.compnylogo.image = images!
}
}
}
here you have to just use. or drag and drop this swift file.
Use this image Loader File this will help you
I'm trying to save a UIImage to NSData and then read the NSData back to a new UIImage in Swift. To convert the UIImage to NSData I'm using the following code:
let imageData: NSData = UIImagePNGRepresentation(myImage)
How do I convert imageData (i.e., NSData) back to a new UIImage?
UIImage(data:imageData,scale:1.0) presuming the image's scale is 1.
In swift 4.2, use below code for get Data().
image.pngData()
Thanks. Helped me a lot. Converted to Swift 3 and worked
To save: let data = UIImagePNGRepresentation(image)
To load: let image = UIImage(data: data)
Use imageWithData: method, which gets translated to Swift as UIImage(data:)
let image : UIImage = UIImage(data: imageData)
Now in Swift 4.2 you can use pngData() new instance method of UIImage to get the data from the image
let profileImage = UIImage(named:"profile")!
let imageData = profileImage.pngData()
Details
Xcode 10.2.1 (10E1001), Swift 5
Solution 1
guard let image = UIImage(named: "img") else { return }
let jpegData = image.jpegData(compressionQuality: 1.0)
let pngData = image.pngData()
Solution 2.1
extension UIImage {
func toData (options: NSDictionary, type: CFString) -> Data? {
guard let cgImage = cgImage else { return nil }
return autoreleasepool { () -> Data? in
let data = NSMutableData()
guard let imageDestination = CGImageDestinationCreateWithData(data as CFMutableData, type, 1, nil) else { return nil }
CGImageDestinationAddImage(imageDestination, cgImage, options)
CGImageDestinationFinalize(imageDestination)
return data as Data
}
}
}
Usage of solution 2.1
// about properties: https://developer.apple.com/documentation/imageio/1464962-cgimagedestinationaddimage
let options: NSDictionary = [
kCGImagePropertyOrientation: 6,
kCGImagePropertyHasAlpha: true,
kCGImageDestinationLossyCompressionQuality: 0.5
]
// https://developer.apple.com/documentation/mobilecoreservices/uttype/uti_image_content_types
guard let data = image.toData(options: options, type: kUTTypeJPEG) else { return }
let size = CGFloat(data.count)/1000.0/1024.0
print("\(size) mb")
Solution 2.2
extension UIImage {
func toJpegData (compressionQuality: CGFloat, hasAlpha: Bool = true, orientation: Int = 6) -> Data? {
guard cgImage != nil else { return nil }
let options: NSDictionary = [
kCGImagePropertyOrientation: orientation,
kCGImagePropertyHasAlpha: hasAlpha,
kCGImageDestinationLossyCompressionQuality: compressionQuality
]
return toData(options: options, type: .jpeg)
}
func toData (options: NSDictionary, type: ImageType) -> Data? {
guard cgImage != nil else { return nil }
return toData(options: options, type: type.value)
}
// about properties: https://developer.apple.com/documentation/imageio/1464962-cgimagedestinationaddimage
func toData (options: NSDictionary, type: CFString) -> Data? {
guard let cgImage = cgImage else { return nil }
return autoreleasepool { () -> Data? in
let data = NSMutableData()
guard let imageDestination = CGImageDestinationCreateWithData(data as CFMutableData, type, 1, nil) else { return nil }
CGImageDestinationAddImage(imageDestination, cgImage, options)
CGImageDestinationFinalize(imageDestination)
return data as Data
}
}
// https://developer.apple.com/documentation/mobilecoreservices/uttype/uti_image_content_types
enum ImageType {
case image // abstract image data
case jpeg // JPEG image
case jpeg2000 // JPEG-2000 image
case tiff // TIFF image
case pict // Quickdraw PICT format
case gif // GIF image
case png // PNG image
case quickTimeImage // QuickTime image format (OSType 'qtif')
case appleICNS // Apple icon data
case bmp // Windows bitmap
case ico // Windows icon data
case rawImage // base type for raw image data (.raw)
case scalableVectorGraphics // SVG image
case livePhoto // Live Photo
var value: CFString {
switch self {
case .image: return kUTTypeImage
case .jpeg: return kUTTypeJPEG
case .jpeg2000: return kUTTypeJPEG2000
case .tiff: return kUTTypeTIFF
case .pict: return kUTTypePICT
case .gif: return kUTTypeGIF
case .png: return kUTTypePNG
case .quickTimeImage: return kUTTypeQuickTimeImage
case .appleICNS: return kUTTypeAppleICNS
case .bmp: return kUTTypeBMP
case .ico: return kUTTypeICO
case .rawImage: return kUTTypeRawImage
case .scalableVectorGraphics: return kUTTypeScalableVectorGraphics
case .livePhoto: return kUTTypeLivePhoto
}
}
}
}
Usage of solution 2.2
let compressionQuality: CGFloat = 0.4
guard let data = image.toJpegData(compressionQuality: compressionQuality) else { return }
printSize(of: data)
let options: NSDictionary = [
kCGImagePropertyHasAlpha: true,
kCGImageDestinationLossyCompressionQuality: compressionQuality
]
guard let data2 = image.toData(options: options, type: .png) else { return }
printSize(of: data2)
Problems
Image representing will take a lot of cpu and memory resources. So, in this case it is better to follow several rules:
- do not run jpegData(compressionQuality:) on main queue
- run only one jpegData(compressionQuality:) simultaneously
Wrong:
for i in 0...50 {
DispatchQueue.global(qos: .utility).async {
let quality = 0.02 * CGFloat(i)
//let data = image.toJpegData(compressionQuality: quality)
let data = image.jpegData(compressionQuality: quality)
let size = CGFloat(data!.count)/1000.0/1024.0
print("\(i), quality: \(quality), \(size.rounded()) mb")
}
}
Right:
let serialQueue = DispatchQueue(label: "queue", qos: .utility, attributes: [], autoreleaseFrequency: .workItem, target: nil)
for i in 0...50 {
serialQueue.async {
let quality = 0.02 * CGFloat(i)
//let data = image.toJpegData(compressionQuality: quality)
let data = image.jpegData(compressionQuality: quality)
let size = CGFloat(data!.count)/1000.0/1024.0
print("\(i), quality: \(quality), \(size.rounded()) mb")
}
}
Links
UTI Image Content Types
CGImageDestinationAddImage(::_:)
Thinking about Memory: Converting UIImage to Data in Swift
Different resize technics
To save as data:
From StoryBoard, if you want to save "image" data on the imageView of MainStoryBoard, following codes will work.
let image = UIImagePNGRepresentation(imageView.image!) as NSData?
To load "image" to imageView:
Look at exclamation point "!", "?" closely whether that is quite same as this one.
imageView.image = UIImage(data: image as! Data)
"NSData" type is converted into "Data" type automatically during this process.
Image to Data:-
if let img = UIImage(named: "xxx.png") {
let pngdata = img.pngData()
}
if let img = UIImage(named: "xxx.jpeg") {
let jpegdata = img.jpegData(compressionQuality: 1)
}
Data to Image:-
guard let image = UIImage(data: pngData) else { return }
For safe execution of code, use if-let block with Data to prevent app crash & , as function UIImagePNGRepresentation returns an optional value.
if let img = UIImage(named: "TestImage.png") {
if let data:Data = UIImagePNGRepresentation(img) {
// Handle operations with data here...
}
}
Note: Data is Swift 3+ class. Use Data instead of NSData with
Swift 3+
Generic image operations (like png & jpg both):
if let img = UIImage(named: "TestImage.png") { //UIImage(named: "TestImage.jpg")
if let data:Data = UIImagePNGRepresentation(img) {
handleOperationWithData(data: data)
} else if let data:Data = UIImageJPEGRepresentation(img, 1.0) {
handleOperationWithData(data: data)
}
}
*******
func handleOperationWithData(data: Data) {
// Handle operations with data here...
if let image = UIImage(data: data) {
// Use image...
}
}
By using extension:
extension UIImage {
var pngRepresentationData: Data? {
return UIImagePNGRepresentation(self)
}
var jpegRepresentationData: Data? {
return UIImageJPEGRepresentation(self, 1.0)
}
}
*******
if let img = UIImage(named: "TestImage.png") { //UIImage(named: "TestImage.jpg")
if let data = img.pngRepresentationData {
handleOperationWithData(data: data)
} else if let data = img.jpegRepresentationData {
handleOperationWithData(data: data)
}
}
*******
func handleOperationWithData(data: Data) {
// Handle operations with data here...
if let image = UIImage(data: data) {
// Use image...
}
}
Swift 5
let the image you create as UIImage be image
image.pngData() as NSData?
Use this for a simple solution
static var UserProfilePhoto = UIImage()
guard let image = UIImage(named: "Photo") else { return }
guard let pngdata = image.pngData() else { return }
UserProfilePhoto = UIImage(data: pngdata)!