Set a UIImageView's Image based on Binary Data - ios

I have an image I'm trying to load from a web service. I've tested the data I got from the web service by adding data:image/gif;base64, before it and entering it as a URL in Chrome and the image loaded perfectly.
In my iOS app, I tried profilePic.image = UIImage.init(data: picData.data(using: .utf8)!) where picData is a string with the contents I tested above, however nothing loaded.
I get the feeling what I did wrong is somewhere in picData.data(using: .utf8)!) but I'm not sure. Any suggestions?
In case it helps, here's the binary data I'm working with: https://pastebin.com/xiWHaPB6

UTF-8 is an encoding for Unicode Strings not arbitrary 8 bit data!
Your if the mime type you've shown is accurate, the data is a Base64 encoded string. The first thing you want to do is convert that string to an unencoded, binary form. Then try creating your UIImage from that:
let unencodedData = Data(base64Encoded: picData)
let image = UIImage(data: unencodedData)

Related

Data to UIImage to UIImageJPEGRepresentation equality failure

Why does this transformation fails to result in the same image data?
let path = Bundle(for: type(of: self)).url(forResource: "Image", withExtension: "jpg")
inputData = try! Data(contentsOf: path!)
let testImage = UIImage(data: inputData)
let testImageData = UIImageJPEGRepresentation(testImage!, 1.0)
expect(testImageData).to(equal(inputData))
From what I understand UIImageJPEGRepresentation and UIImagePNGRepresentation can strip the image of meta data. Is that the reason?
There is no particular reason why two JPEG files showing the same image would be identical. JPEG files have lots of header info, different compression algorithms, etc. And even if both files have a compression level of 1 (do they?) they are both lossy, so something will differ every time you expand and recompress. Your expectations here are just wrong. But then it also sounds like you’re trying to test something that does not need testing in the first place.
I was facing the same Issue, and was able to solve using UIImagePNGRepresentation to convert the UIImage to Data, and then compared to see if both Data were equal.

Decompress Base64 Encoded Image Bytes in Swift

I am developing an iOS Application in Swift for use by customers of the company for which I work. In addition to the iOS application, I am also making the backend API with ASP.Net Core. The method I have chosen to use for sending images is a compressed base64 encoded string representation of the image in a JSON array. This is to save on bandwidth and to make it easier to send multiple images.
On the API side, I am using the .NET Class System.IO.Compression.DeflateStream to compress the image bytes in memory before encoding them to a base64 string and sending them to the iOS application.
On the iOS side, I am a little confused as to what the process would be for decoding the string and decompressing the data to create a UIImage object for display in a UIImageView.
This all works without compression, but I wanted to try this to save on bandwidth. However, it's very possible that this is not the optimal solution, and I am open to change. Below is the snippet of code I am using to convert the base64 string to a Data object, then creating a UIImage object from that.
static func imageComplete(data json: JSON) -> [UIImage] {
var images: [UIImage] = []
for imageString in json.arrayValue {
if let compressedImageData = Data(base64Encoded: imageString.stringValue),
let image = UIImage(data: compressedImageData) {
images.append(image)
}
}
return images
}
TL;DR
In Swift, I want to decompress image bytes encoded as a Base64 string returned from an ASP.Net Core WebAPI.

iOS Swift base64encoding different than PAW app Base64 Encoding

Hoping to get some help with this. I am trying to post an image to a server and it requires base64 encoding of a PNG file. When I use the PAW app and encode the image everything shows up on the server beautifully. When I attempt to do the same with iOS Swift 4, the string produced is similar but also has differences and thus an incorrect image. Any idea of how to match the string that is correctly created in the PAW app in iOS. I have included code below along with screenshots of the strings (small samples) created.
Thanks!
let image : UIImage = UIImage(named:"STG.png")!
let imageData = UIImagePNGRepresentation(image)
var base64String = imageData?.base64EncodedString(options: [])
You are not comparing the same data at all. Loading the png into a UIImage and then converting the UIImage into a new png representation does not result in the same set of bytes at all.
You need to directly load the png file into a Data instance without doing any conversion.
let imageURL = Bundle.main.url(forResource: "STG", withExtension: "png")!
let imageData = try! Data(contentsOf: imageURL)
var base64String = imageData.base64EncodedString(options: [])
You might also need to try different options in the call to base64EncodedString.
Ok went down several rabbit holes and found some folks with similar issues to this. I eventually solved it by switching over to Alamofire instead of using the native urlsession. I also found out the server I was posting to would allow for multipart/form-data as well which I ended up using for my request. I was unable to get that to work using the native urlsession either.

swift gzip data to string issue

I use gzip library to convert data to gzip data
If I want to get string from data I do String(data: data, encoding: .utf8) . But if I do the same for gzip data I get nil string, because as far as I understand it's impossible to convert gzip data to string with .utf8 encoding.
I need that because I want to compare data with a server developer (because he sometimes he says that my data is incorrect format, but sometimes it's ok, and that's strange because I use the same library, and I have thoughts that may be the problem is on server side).
Is there any way to convert gzip data to any string to compare it then later?
If this is just for debug purpose, then I think the quickest way is:
let myGZipNSData = myGZipData as! NSData //I wrote a "!" just for the sample)
print("myGZipNSData: \(myGZipNSData)")
It should output:
myGZipNSData: <5b226d79 41727261 7956616c 75653022 2c226d79 41727261 7956616c 75653122 5d>
This relies on -description method of NSData which print "<hexValue>".
Do not rely on it on release version, almost never rely on -description (yes, Apple could change the behavior of -description in next release. It happened on a different class).
Other way (safer) to get almost the same result, you can check this question: How to convert Data to hex string in swift which you get you the same result (almost, less space, and no </>) as the previous one.
Other way: Base 64
Use base64EncodedString() method of Data:
let base64Str = myGZipData?.base64EncodedString()
print("base64Str: \(base64Str!)")
Output:
base64Str: WyJteUFycmF5VmFsdWUwIiwibXlBcnJheVZhbHVlMSJd
Now, there should be other way:
Have a array representation with Int values (between 0/255 instead of hex), but it seems to be for debug purpose so check if you can "reproduce the current solutions" (working/fast implementation) I gave you, and check with the server developer what he/she can do on his/her side too to compare.
Note:
For the purpose of this sample, myGZipData is constructed this way:
let array = ["myArrayValue0", "myArrayValue1"]
let myGZipData = try? JSONSerialization.data(withJSONObject: array, options:[])
It's not really a GZipData, but the goal was to quickly have a Data object "big enough".

Reading Websites in iOS

I am trying to read data from my API. I am not using JSON data because the API doesn't return an array, just a line of text. Anyways, I am using the following code to read the text from the API.
func contactVetApi(url:String){
let nsUrl = NSURL(string:url)
let task = NSURLSession.sharedSession().dataTaskWithURL(nsUrl!){
(data, response, error) in
print(data)
}
task.resume()
}
I am calling this function in the ViewDidLoad function of my ViewController file. As you can see, it takes a parameter that is a string. The parameter is the URL to read. It then translates the string into a NSUrl so it can be used with the sharedSession. I then initialize the shared session and create a data task with that url. I then print out the data it returns. The only issue is that the output isn't what I am expecting. What I am expecting is for it to say, "Future home of something quite cool." Although, this is what I am getting.
Optional(<46757475 72652068 6f6d6520 6f662073 6f6d6574 68696e67 20717569 74652063 6f6f6c>)
Optional(<46757475 72652068 6f6d6520 6f662073 6f6d6574 68696e67 20717569 74652063 6f6f6c>)
I need help figuring out why it is printing that out instead of what I am expecting. In case it is needed, the api url is http://apis.wilsonfamily5.org/vet/about.php. Before anybody asks though, I did add into the info.plist file the disabling of the iOS 9 app transport security. If you need any extra information to help me solve this problem, I would be more then happy to give it to you. I want to thank you in advance.
You currently are printing a NSData object, which will always look like that jibberish. What you actually want however is to convert the NSData to a NSString or String to create a human readable form:
var dataAsString = NSString(data: data, encoding: NSUTF8StringEncoding)
Taken from this answer.

Resources