Post a UIImage to the web

So here is something a lot of people have been wondering to do in the forums. How do I take a UIImage or any image and post it to a website. So this will go over how to do that.

There are two ways to tackle this issue. One we can base64 encode the file and post is normally inside a XML or JSON instance or we can simulate a normal HTML post. This tutorial will go over the HTML post.

This will start off where Using a UIImagePickerController left off. So you can grab the code and start there if you want. So lets begin.

So first open up testPickerViewController.h and we want to add in one outlet and one action.

So here is the outlet we want to add
IBOutlet UIButton *upload;
Here is the action we want to add
IBOutlet UIButton *upload;
Now double click on testPickerViewController.xib and we need to connect the new outlet and action. We also need to create our new upload button. So drag around the current items and place the new button under the grab button. Then you want to make the button hidden by default. The option is as shown below. Do get to that selector you do Tools -> Attributes Inspector

You might also want to setup your UIImageView to aspect fit. If the image is larger then your box you created in IB it will shrink the image to fill it. Click on the UIImageView and in the Attributes Inspector select the following drop down for Mode

Now you want to make your connections to the new outlet and action we created in code. So here is another screenshot of what they should look like

Now it is back to the code. So save this and you can quit IB. 

So open up testPickerViewController.m and find the imagePickerController method and at the end add 
upload.hidden = NO;

That will show our upload button once a image is set.

So now we need to create our uploadImage method that gets called then the button is pressed. So it is below and hopefully pretty well commented.

- (IBAction)uploadImage {
	/*
	 turning the image into a NSData object
	 getting the image back out of the UIImageView
	 setting the quality to 90
	*/
	NSData *imageData = UIImageJPEGRepresentation(image.image, 90);
	// setting up the URL to post to
	NSString *urlString = @"http://iphone.zcentric.com/test-upload.php";

	// setting up the request object now
	NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
	[request setURL:[NSURL URLWithString:urlString]];
	[request setHTTPMethod:@"POST"];

	/*
	 add some header info now
	 we always need a boundary when we post a file
	 also we need to set the content type

	 You might want to generate a random boundary.. this is just the same
	 as my output from wireshark on a valid html post
	*/
	NSString *boundary = [NSString stringWithString:@"---------------------------14737809831466499882746641449"];
	NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary];
	[request addValue:contentType forHTTPHeaderField: @"Content-Type"];

	/*
	 now lets create the body of the post
	*/
	NSMutableData *body = [NSMutableData data];
	[body appendData:[[NSString stringWithFormat:@"rn--%@rn",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
	[body appendData:[[NSString stringWithString:@"Content-Disposition: form-data; name="userfile"; filename="ipodfile.jpg"rn"] dataUsingEncoding:NSUTF8StringEncoding]];
	[body appendData:[[NSString stringWithString:@"Content-Type: application/octet-streamrnrn"] dataUsingEncoding:NSUTF8StringEncoding]];
	[body appendData:[NSData dataWithData:imageData]];
	[body appendData:[[NSString stringWithFormat:@"rn--%@--rn",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
	// setting the body of the post to the reqeust
	[request setHTTPBody:body];

	// now lets make the connection to the web
	NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
	NSString *returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];

	NSLog(returnString);
}

So now if you build and go you will upload the image you selected to the following image URL

http://iphone.zcentric.com/uploads/ipodfile.jpg

Below is my PHP file I am using to handle uploads.

$uploaddir = './uploads/';
$file = basename($_FILES['userfile']['name']);
$uploadfile = $uploaddir . $file;

if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
        echo "http://iphone.zcentric.com/uploads/{$file}";
}

It is nothing special. I do an echo so you can see in the console what the file is. If you switch the filename=”" part in the uploadImage section it will be placed as another file.

Files will be removed once they are 10 minutes old on the server so they won’t last but you can use it as a playground.

As always here is my code.

About mike
Currently works for OpenSky as a Senior Linux Admin. He has a wonderful wife Thanuja and 2 great dogs. His major side project is Photoblog.

Comments

113 Responses to “Post a UIImage to the web”
  1. Sweetness, loved this one.

  2. Name says:

    String lines like this are weird:

    NSString *boundary = [NSString stringWithString:@"---------------------------14737809831466499882746641449"];

    All you need to do is this:

    NSString* boundary = @”—————————14737809831466499882746641449″;

    This line is also weird:

    [body appendData:[NSData dataWithData:imageData]];

    Just use:

    [body appendData:imageData];

    Also, you’re leaking returnString.

  3. Tristan Harmer says:

    Thanks for the example! Really helped me out.

    NSData *imageData = UIImageJPEGRepresentation(image.image, 90);

    should be

    NSData *imageData = UIImageJPEGRepresentation(image.image, 0.9);

    It really brought the file size down for me. It would seem 90 means super mega quality :)

  4. Ilesh says:

    Good example and explained well..Thanks..

    How can I upload or post sheet(.xls) file to server ? Can anyone have idea ?

  5. David says:

    the code works fine uploading to this server, when i copy paste the php file to my own server i get the following though:

    Warning: move_uploaded_file(./pics/ipodfile.jpg) [function.move-uploaded-file]: failed to open stream: Permission denied in /Users/davidkatz/Sites/webservice/upload.php on line 6

    Warning: move_uploaded_file() [function.move-uploaded-file]: Unable to move ‘/private/var/tmp/phpwPtGZx’ to ‘./pics/ipodfile.jpg’ in /Users/davidkatz/Sites/webservice/upload.php on line 6

    suggestions?

  6. mikezupan says:

    webserver doesn’t have rights to write to that directory

  7. David says:

    i’m running apache on mac os x, do you know how i can configure permissions?

    thanks.

  8. David says:

    ok, i got it to work – all i did was set permissions to read&write for everyone in os x’s get info dialogue for the foler.

    thanks a lot for your help.

  9. Sho says:

    works perfect! looking forward to see more :)

  10. Warning: mysql_connect() [function.mysql-connect]: Can't connect to MySQL server on 'localhost' (10048) in C:AppServwwwmegadorgenconfig.php on line 5 Can't Connect says:

    Warning: mysql_connect() a href=’function.mysql-connect’>function.mysql-connect]: Can’t connect to MySQL server on ‘localhost’ (10048) in C:AppServwwwmegadorgenconfig.php on line 5
    Can’t Connect

  11. jon says:

    I tried appending another text variable but it is not sending correctly. Have you done this?

    i tried adding this after the ” NSMutableData *body = [NSMutableData data];” line but it failed.

    [body appendData:[[NSString stringWithFormat:@"rn--%@rn",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[[NSString stringWithString:@"Content-Disposition: form-data; name="name""] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[@"rnBOBrn" dataUsingEncoding:NSUTF8StringEncoding]];

  12. David H Dennis says:

    For adding text data, you can use GET data instead of post, which is easier to code. That is, you can add the variable=value&variable=value etc to the URL.

    At least on Ruby on Rails, the example fails with a form error when you use it as stated. You do not want the first “rn” before the first instance of the separator. Remove that and it works on Rails.

    Hope that helps.

    D

  13. Jitendra says:

    Please tell, how image will be retrieved from request at java server?

    thanks

  14. Naren says:

    Brilliant!!

    Jitendra,
    For Java, Post to a servlet and retrieve the image as below

    NOTE: The below assumes that only the imageData is being posted with NO HEADERS (boundary, content-type etc).. add them in after you can read the image first….
    ie. HTTP POST ONLY imageData in the body.
    [body appendData:[NSData dataWithData:imageData]];

    protected void processRequest(HttpServletRequest request, HttpServletResponse response) {
    BufferedImage bImage = ImageIO.read(request.getInputStream());

  15. Naren says:

    Thanks a lot! Works wonderfully :)

    I customized it with an Actionsheet to both choose from library as well as from the camera!!

  16. Wes says:

    Anyone know how to do the same thing but with .caf audio files?

  17. Kimando says:

    Hi… please send me a Java servlet and a php file for uploads !!!

    Thanks

  18. jz says:

    thanks for this, it was very helpful!

  19. Daniel Murphy says:

    Hi thanks for this tutorial it’s a great help.

    Small problem I’m having when trying it out with my own server – i create a php file just like you have and I change the obj c code to point the url to my url location.

    I have my uploads folder created etc. however when I try it out there is no sign of the pic being uploaded. Any ideas? It all works fine when I try it with this server.

    I’m pretty sure it aint permissions either as i have r/w access on all dirs.

    any more ideas much appreciated.

  20. This is freaking outstanding ! Thanks so much!

  21. Chuck says:

    Great job and amazing post.

    Quick question.
    How do you point to a different file other than hard-coding ipodimage.jpg…

    In other words, if I’m creating a new file (an audio file or image) how would I pull that out of the home directory when posting it?

    Thanks!

  22. GrM says:

    Hey ! thank you so much for this post.

    I’ve been able to make it work in just few minutes.

    :p

  23. Ian says:

    When I try this code, I am getting the error on the iPhone client:

    “The page was not displayed because the request entity is too large.”

    Request Filtering on the webserver is set to content length of 30,000,000 bytes. The image to be sent is 130k

    Please help!

  24. iPatx says:

    Is it possible to send 2 UIImage in only one form?
    What I have to change to do this ?

  25. Correct me if I’m wrong, but when using JPEG representation, wouldn’t the highest compression value be 1.0? So:

    “NSData *imageData = UIImageJPEGRepresentation(image.image, 90);”

    Should be

    NSData *imageData = UIImageJPEGRepresentation(image.image, 0.9);”

    If I am wrong, please do correct me, thanks.

  26. appsindex says:

    Awesome post, straight to the point as it should be.

  27. Aryan says:

    What is the boundary, and what does that boundary string mean?
    “—————————14737809831466499882746641449″]”

  28. Mike says:

    the boundary is just a unique identifier for the server to use to parse the incoming data.. It is a random string that must be the same.

  29. dlewis says:

    Is there anyway to make the images it uploads bigger?

    It shrinks them all to like 320×240. I would like them to be bigger like 1024 PX wide at least.

    Thanks

  30. narendar says:

    Hi, how can I fetch the image request and can save in a folder using ASP VB.net,

    Is any one have idea about it , please provide any sample code for that ??

    Thanks,
    Narendar

  31. James says:

    i’d love to see the code for test-upload.php

  32. Chintan says:

    How to upload .caf files recorded on iphone to web server?

  33. Keiran says:

    When I upload my file to my local server it appears but is zero kb and doesn’t open. I am uploading a file from the default photo library on the iPhone simulator. Any ideas?

  34. Ad says:

    Hi guys,
    I have the same problem as Keiran has… Any clues ?

  35. Mike says:

    @keiran and Ad

    Your backend script is probably wrong and just creating a null file.

  36. esko2300 says:

    I get the file to upload when im sending it to the website you post tell us to post it to in your code but when i try and put in the website i need to post it to for some reason i cant get the image to post . ne idea on what may be going wrong?

  37. esko2300 says:

    actually im getting this error
    Failed to save the videos metadata to the filesystem. Maybe the information did not conform to a plist.
    ne idea what it means

  38. esko2300 says:

    I am trying to send an image to a differnt server type i believe, u r using .php the website type i am sending to is .asmx would there be a few differnt methods i would need to use?

  39. Ryan says:

    Hoping you had a quick ref. on how to include variables in the post command. I need to include 4-5 different variables to request on the server. I am trying to read examples and figure it out, but it seems foggy.

    Thanks for the great code!

  40. Sunil Jagnani says:

    Thanks…. That helped a lot

  41. Janarthanan says:

    Hi,
    I am using the code you have given…Below here is your code…

    /*
    now lets create the body of the post
    */
    NSMutableData *body = [NSMutableData data]; ****** line1
    [body appendData:[[NSString stringWithFormat:@"rn--%@rn",boundary] dataUsingEncoding:NSUTF8StringEncoding]];****** line2
    [body appendData:[[NSString stringWithString:@"Content-Disposition: form-data; name="userfile"; filename="ipodfile.jpg"rn"] dataUsingEncoding:NSUTF8StringEncoding]];****** line3
    [body appendData:[[NSString stringWithString:@"Content-Type: application/octet-streamrnrn"] dataUsingEncoding:NSUTF8StringEncoding]];****** line4
    [body appendData:[NSData dataWithData:imageData]];
    [body appendData:[[NSString stringWithFormat:@"rn--%@--rn",boundary] dataUsingEncoding:NSUTF8StringEncoding]];****** line5
    // setting the body of the post to the reqeust
    [request setHTTPBody:body];****** line6

    ——————
    while building my application an exception at line number 5…..it is saying like below:[NSConcreteMutableData appendData:dataUsingEncoding:]: unrecognized selector sent to instance 0x10c7b40

    please help me to resolve this error!!!

  42. Dave says:

    Is there an updated version of this as functions are now depreciated

  43. Jana says:

    If I want to upload dynamic images(file name may be anything), what should I put as image file name?

  44. Brij says:

    I need to pass some parameters with the image. I found the solution here:
    http://urenjoy.blogspot.com/2009/12/pass-parameter-web-service-image-upload.html

    Hope, It helps.

  45. roocell says:

    make sure you have in php.ini
    upload_max_fileszie=5M

    a lower value (default is 2M) results in tmp_name being NULL and move_uploaded_file() fails.

  46. zyq says:

    What’s the meaning of “—————————14737809831466499882746641449″

    and how to add other POST data together with it?

    for example, email=xxx@xx.com user=someone

    thanks very much.

  47. Jason says:

    Works great on my php boxes. But I’m having trouble getting it to work with my iis/asp box
    I can upload files using a HTML form on the server but I get errors when I do it from the phone / simulator.
    Has anybody got this to work having the server-side scripts being asp?

  48. Abdul Samad says:

    Hurry
    Thanx Buddy u r great i have have struck on this prooblem for more than 50 hours. its because of ur code i am able to figure out that problem..
    That code realyy works very fine i am very thankful to u…..

  49. Matthew Bryant says:

    It nearly works for me via asp.net. The only problem I have is that the image won’t open in paint but it only opens in adobe photoshop does anyone else hae this problem usign asp or php? Thanks Mat

  50. Matthew Bryant says:

    Also great code by the way is has helpeda a lot

Trackbacks

Check out what others are saying about this post...
  1. [...] is a blog post about it Post a UIImage to the web | Iphone Noob Here is the meat of the code to post [...]

  2. [...] have a blog post about this Post a UIImage to the web | Iphone Noob Looks like your boundaries are bad __________________ Iphone Noob iPhone Development Blog. [...]

  3. [...] this? Post a UIImage to the web : Iphone Noob __________________ My Apps on AppStore : gScale (guitar scales reference), [...]

  4. [...] is a blog post about it Post a UIImage to the web | Iphone Noob Here is the meat of the code to post [...]

  5. [...] Post a UIImage to the web : Iphone Noob (tags: iphone programming photoupload) This entry was posted on Thursday, March 10th, 2011 at 6:06 pmand is filed under del.icio.us. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site. [...]

  6. [...] I have found quite a bit of advice on the matter on the internet but nothing I try seems to work. This is my objective-c code, based on the tutorial here: http://iphone.zcentric.com/2008/08/29/post-a-uiimage-to-the-web/ [...]



Speak Your Mind

Tell us what you're thinking...
and oh, if you want a pic to show with your comment, go get a gravatar!