4

Currently, I'm trying to upload a base64 encoded image to a php server which is then storing the base64 string in a MySQL database. Currently, the code is uploading the data and storing it into the MySQL database. However, when I attempt to retrieve the image by specifying the URL used to retrieve the image, a missing image link with the question mark is shown. I have no idea why this is happening since both uploading and displaying base64 encoded images seems to be working just fine with my Android app.

Here is the Swift code I'm using to encode and upload to the server:

    let image: UIImage = imgProfilePic.image!

    let size = CGSizeApplyAffineTransform(image.size, CGAffineTransformMakeScale(0.3, 0.3))
    let hasAlpha = false
    let scale: CGFloat = 0.0 // Automatically use scale factor of main screen

    UIGraphicsBeginImageContextWithOptions(size, !hasAlpha, scale)
    image.drawInRect(CGRect(origin: CGPointZero, size: size))

    let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    var imageData = UIImageJPEGRepresentation(scaledImage, 0.9)
    var base64String = imageData.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0)) // encode the image

    var cd = CoreDataUser(pstrContext: "this")

    var params = "strUsername=" + cd.getUsername()
    params = params + "&strPassword=" + cd.getPassword()
    params = params + "&blbProfilePic=" + base64String

Here is the PHP code where the base64 string is being decoded and displayed in the browser. This is working fine for images that are uploaded by my Android code, but it just shows a broken image link for images uploaded by my Swift code.

 if ($rows) { 
    foreach ($rows as $row) { 
    $data = base64_decode($row["fblbProfilePic"]);
    $image = imagecreatefromstring($data);
    header('Content-Type: Image/jpeg');
    imagejpeg($image);
//file_put_contents("test.jpg", $data);
//var_dump($data);

    //echo base64_decode($row["fblbPicture"]);
    /    /echo '<img src="data:image/jpg;base64,' . $row["fblbPicture"]     . '" />';
     }
play2win
  • 331
  • 8
  • 25
  • Please share the code where you are downloading and decoding it to base64.. entire code from webservice call. – Arun Gupta Apr 11 '15 at 19:40
  • Thanks for the response, Arun. I edited my question to contain the PHP code where the base64 image string is being decoded and added displayed in the browser. – play2win Apr 11 '15 at 19:47
  • What you can try is call the same service from iPhone,extract the imagestring decode it and display it in imageView. If this works then you are sending it right. Only issue would be the way encoding is happening as in iOS we are using NSDataBase64EncodingOptions whose equivalent needs to be seen in php. – Arun Gupta Apr 11 '15 at 19:55
  • Thanks again for the response. I actually did exactly what you recommend here. I encoded the image into a base64 string in Swift, then I took the encoded string and base64 decoded it in Swift and was able to successfully display it in another UIImageView. Something seems to be happening at the server to cause a corruption in the base64 string or something. I'm at a loss in figuring it out at the moment. – play2win Apr 11 '15 at 19:58
  • Did you took the encoded image from server or decoded it locally in iOS? Is your server returning the image directly as data or in json key valur pair? – Arun Gupta Apr 11 '15 at 20:00
  • The base64 image string is extracted from the MySQL database and decoded in PHP on the server and then displayed as an image to the browser. The app doesn't perform any of the decoding. The app just requests the URL for the image and grabs the image that is displayed. – play2win Apr 11 '15 at 20:18
  • Then is seems to be issue with encodingoptions of iOS. Did you try to upload a image from andriod device and display in iOS device. – Arun Gupta Apr 11 '15 at 20:29
  • Yes, I'm able to upload from my Android application and display in iOS successfully. I agree with you. It does seem to be something with encoding option in Swift, but I'm unsure which options it pertains to. I checked out some options dealing with line endings of the encoded string, but I don't think those apply. I'm pretty much stuck unable to figure this out at the moment. – play2win Apr 11 '15 at 20:32
  • Also try out this, before convertig image to base64 you are scaling it. So for now send the image as it is instead of scaling and doing transform. – Arun Gupta Apr 11 '15 at 20:43
  • Trying using a third party base64 library class. You can use Base64.h and Base64.m classes for encoding and decoding. May be this could give some insight on the problem. – Arun Gupta Apr 11 '15 at 20:55
  • I'll give those a try. Thanks. Also, I'm wondering if some special characters in the base64 encoded string are causing problems in the POST method when the data is being sent to the server? – play2win Apr 11 '15 at 21:15
  • That wont be a problem. Else your android code will also be giving same issue. Also base64 string is plan characters and number. As far as i know it doesnt have any special characters. If you think so just try to print the encoded string you are sending. – Arun Gupta Apr 11 '15 at 21:17
  • I think you're right. After researching it a little more, I don't think there are any special characters causing data loss in the POST method sending the data to the server. I hope I can figure this thing out quickly. I've already spent nearly all day on it. I certainly appreciate your help, Arun. – play2win Apr 11 '15 at 21:24
  • The best way to find the root cause of it would be to decoding the image in iOS. Just for testing, instead of sending decoded string send the original string from mysql db to iOS in json format. Extract the image string and decode it back in nsdata using the same encodingoptions and display in uiimageview. If it displays then definately its base64 mismatch between ios and php. – Arun Gupta Apr 11 '15 at 21:34
  • I tried something similar to what you've suggested. I took the base64 string from a println() statement in iOS and I manually pasted it into my PHP file and assigned it to a variable to be decoded and displayed in the browser. It showed up perfectly when I did that. I then manually copied the base64 string into the PHP file where the INSERT statement is performed. Then I ran the PHP code to extract it and display it in the browser. That worked perfectly, also. The problem seems to be somewhere in the POST method when the data is sent to the server. I may try printing out the POST results next. – play2win Apr 11 '15 at 23:30
  • Just check this in your iOS code you are using key for base64 string as "&blbProfilePic=" but in php code you are using "fblbProfilePic". Can this be issue. Other then that i dont think there is issue anywhere else. – Arun Gupta Apr 11 '15 at 23:40
  • Also i dont thing there is any need to & in your params string – Arun Gupta Apr 11 '15 at 23:58
  • After a little more research, I found some information that says I need to set a boundary of characters around the data for the image before executing the POST operation to the server. I'm looking more into that to see if that's the solution. – play2win Apr 12 '15 at 13:24
  • Not sure if that is correct. I am also sending the base64 string of different documents like pdf, word, ppt... to server and decode the same on device and it works perfectly.... we are missing something very silly here and i tell you silly things are very difficult to catch. They will make you scratch your head :)... by the way i will try the same thing and will let you know.. – Arun Gupta Apr 12 '15 at 16:20

3 Answers3

2

I was able to get this working by percent encoding the base64 string before posting it to the PHP server. Hope this helps someone else.

play2win
  • 331
  • 8
  • 25
2

Just supplying some helpful Swift 3.0 code here on the back of play2win's self-answer:

let data:Data = UIImagePNGRepresentation(myUIImageView.image!)!
let base64String:String = data.base64EncodedString(options: Data.Base64EncodingOptions(rawValue: 0))
let imageStr:String = base64String.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
dijipiji
  • 3,063
  • 1
  • 26
  • 21
0

You should first decode your base64 image in to data and save on server side so that we will get that saved location path of your in response that you wanted.. hope this help you...

user3306145
  • 76
  • 2
  • 12
  • Thank you for the response. The data for the image is getting saved in the MySQL database. I'm using the same steps in Swift that I used for the Android app and the Android app is working fine. First I get the image, then I encode the image into a base64 string, then I send it to the server which stores the base64 string in the database. When I retrieve the image, I select it from the database and decode the base64 string with PHP and display the decoded image in the browser which is then picked up by the app. For some reason the Swift code isn't working properly, though. – play2win Apr 11 '15 at 19:37