Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Base64 encoded image corrupted during transfer to server

For some reason i can't upload a jpeg file to a server using the post method in NSURLRequest

I have an android app that uses the same php code and can upload and download images fine by converting the image to a byte array and then using base64 encoding to send and receive.

My iPhone app downloads the image fine, The php script encodes using base64 and i use a base64 decoder in my iPhone app which I then convert into an image. This works fine.

However the uploading of the image doesn't work.

I convert the image to a base64 encoded string (I've used a few different methods for the base64 encoding and they all give the same result) then I post to the server, decode on the server side and save to file on the server.

The resulting decoded file on the server is a corrupt jpeg image. The corrupt file size is 3 times as many bytes as it should be.

The base64 encoded string generated for the upload is also very different to the base64 encoded string generated when downloading the same jpeg file from the server (ie. the valid image file that I uploaded using an ftp service).

My code is shown below along with the php script to receive the image.

I believe there is something happening with escaping characters which is causing the base64 string to become corrupted during the transfer but can't work it out.

Why is my base64 string being corrupted during transfer?

NSString* comments = @"comments to go with image";


NSData *data = UIImageJPEGRepresentation(_imageView.image, 1);
NSString *base64EncodedImage = [NSString base64StringFromData: data length: data.length];



//load the team posts so we know what items have been posted and what haven't
NSMutableDictionary *postDict = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                 comments, @"comment",
                                 base64EncodedImage , @"image",
                                 nil];


NSMutableArray *parts = [[NSMutableArray alloc] init];
for (NSString *key in postDict) {
    NSString *part = [NSString stringWithFormat: @"%@=%@", key, [postDict objectForKey:key]];
    [parts addObject:part];
}

NSString *encodedDictionary = [parts componentsJoinedByString:@"&"];

NSData *postData = [encodedDictionary dataUsingEncoding:NSUTF8StringEncoding];

NSString* url = @"http://www.scroppohunt.com/upload.php";
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
                                                   timeoutInterval:10.0];
[request setHTTPMethod:@"POST"];
[request setValue:[NSString stringWithFormat:@"%d", postData.length] forHTTPHeaderField:@"Content-Length"];
[request setValue:@"application/x-www-form-urlencoded charset=utf-8" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:postData];

NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
if (connection) {
    _data = [[NSMutableData data] init];

}     

and the php script that receives the image

<?php


$comments = $_REQUEST['comment'];


//do some database stuff with the comments

////////////////////////////////////////
//save the file to the images folder
///////////////////////////////////////////

$base=$_REQUEST['image'];

if(strlen($base) > 0)
{

    // base64 encoded utf-8 string

    $binary=base64_decode($base);

    $file = fopen("postImages/test.jpg", 'wb');

    fwrite($file, $binary);

    fclose($file);
}

//display the bae64 encoded string taht was uploaded
echo $base;

?>

like image 511
Matthew Bailey Avatar asked Mar 08 '13 05:03

Matthew Bailey


People also ask

Is it good to store Base64 image in database?

While base64 is fine for transport, do not store your images base64 encoded. Base64 provides no checksum or anything of any value for storage. Base64 encoding increases the storage requirement by 33% over a raw binary format.

Is there a limit to Base64 encoding?

The maximum length in 2732 characters. The result of the function is a varying length character string in CCSID 1208 that contains the bytes of character-string as a Base64-encoded string.

Can Base64 encoding be reversed?

Encoded data has similar paddings at the end as base64, but definitely it is not base64. Probably crypted with some SHA-like algorithm. With the data you provided, I would say that it is not possible to reverse-engineer the encoding process.

What is the problem that Base64 encoding method design to solve?

Base64 encoding schemes are commonly used when there is a need to encode binary data that needs be stored and transferred over media that are designed to deal with textual data. This is to ensure that the data remains intact without modification during transport.


2 Answers

Well, it's been a while when you asked this question, but if anyone (like me) find this question, this may help:

In your Base64 encoded image, you should replace all occurrences of "+" character, with "%" character. Translated into code, it would be:

NSString* encodedImageString = [base64EncodedImage stringByReplacingOccurrencesOfString:@"+" withString:@"%2B"];

Then, instead of adding base64EncodedImage in postDict, you should add encodedImageString.

That way, your postDict will look like this:

NSMutableDictionary *postDict = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                 comments, @"comment",
                                 encodedImageString , @"image",
                                 nil];

I think this will solve the problem, at least, was for me.

Cheers.

like image 51
Dimmy3 Avatar answered Sep 21 '22 21:09

Dimmy3


I also had this problem. For me, what was happening was that all the "+" were replaced with "space" after being sent to the server. There was no other such corruption:

enter image description here

like image 31
user7191867 Avatar answered Sep 18 '22 21:09

user7191867