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:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:@"Content-Disposition: form-data; name=\"userfile\"; filename=\"ipodfile.jpg\"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:@"Content-Type: application/octet-stream\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[NSData dataWithData:imageData]];
[body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",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.
Comments
69 Responses to “Post a UIImage to the web”
Leave a Reply




[...] is a blog post about it Post a UIImage to the web | Iphone Noob Here is the meat of the code to post [...]
Sweetness, loved this one.
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.
[...] 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. [...]
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
Good example and explained well..Thanks..
How can I upload or post sheet(.xls) file to server ? Can anyone have idea ?
[...] Post a UIImage to the web [...]
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?
webserver doesn’t have rights to write to that directory
i’m running apache on mac os x, do you know how i can configure permissions?
thanks.
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.
works perfect! looking forward to see more
Warning: mysql_connect() a href=’function.mysql-connect’>function.mysql-connect]: Can’t connect to MySQL server on ‘localhost’ (10048) in C:\AppServ\www\megadorgen\config.php on line 5
Can’t Connect
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:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:@"Content-Disposition: form-data; name=\"name\""] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"\r\nBOB\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[...] this? Post a UIImage to the web : Iphone Noob __________________ My Apps on AppStore : gScale (guitar scales reference), [...]
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 “\r\n” before the first instance of the separator. Remove that and it works on Rails.
Hope that helps.
D
[...] is a blog post about it Post a UIImage to the web | Iphone Noob Here is the meat of the code to post [...]
Please tell, how image will be retrieved from request at java server?
thanks
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());
Thanks a lot! Works wonderfully
I customized it with an Actionsheet to both choose from library as well as from the camera!!
Anyone know how to do the same thing but with .caf audio files?
Hi… please send me a Java servlet and a php file for uploads !!!
Thanks
thanks for this, it was very helpful!
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.
This is freaking outstanding ! Thanks so much!
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!
Hey ! thank you so much for this post.
I’ve been able to make it work in just few minutes.
:p
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!
Is it possible to send 2 UIImage in only one form?
What I have to change to do this ?
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.
Awesome post, straight to the point as it should be.
What is the boundary, and what does that boundary string mean?
“—————————14737809831466499882746641449″]”
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.
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
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
i’d love to see the code for test-upload.php
How to upload .caf files recorded on iphone to web server?
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?
Hi guys,
I have the same problem as Keiran has… Any clues ?
@keiran and Ad
Your backend script is probably wrong and just creating a null file.
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?
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
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?
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!
[...] http://iphone.zcentric.com/?p=218 [...]
Thanks…. That helped a lot
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:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];****** line2
[body appendData:[[NSString stringWithString:@"Content-Disposition: form-data; name=\"userfile\"; filename=\"ipodfile.jpg\"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];****** line3
[body appendData:[[NSString stringWithString:@"Content-Type: application/octet-stream\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];****** line4
[body appendData:[NSData dataWithData:imageData]];
[body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",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 0×10c7b40
please help me to resolve this error!!!
Is there an updated version of this as functions are now depreciated
If I want to upload dynamic images(file name may be anything), what should I put as image file name?
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.
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.
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.
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?
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…..
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
Also great code by the way is has helpeda a lot
Matthew may i see your code in asp.net? well i and my friend has tried to create in aspx file but it can’t work at all. Please help..
This works in asp.net!!!!!!!!!!!!!!!!!!!
HttpFileCollection MyFilecollection = Request.Files;
MyFilecollection[0].SaveAs(Server.MapPath(“~/ImageStore/” + MyFilecollection[0].FileName));
Full code is shown below.Replace test-upload.php with your asp page (mine is recievefile.aspx)
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web.Security;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Data.Odbc;
using System.Data.SqlClient;
using System.Diagnostics;
using System.IO;
using System.Web.Util;
using System.Reflection;
using System.Drawing;
using System.Net;
using System.Text.RegularExpressions;
public partial class recievefile : System.Web.UI.Page
{
public DatabaseGateway dg = new DatabaseGateway();
protected void Page_Load(object sender, EventArgs e)
{
HttpFileCollection MyFilecollection = Request.Files;
MyFilecollection[0].SaveAs(Server.MapPath(“~/ImageStore/” + MyFilecollection[0].FileName));
}
}
MyFilecollection[0].SaveAs(Server.MapPath(“~/ImageStore/” + MyFilecollection[0].FileName));
}
Sorry repeated a bit of code at bottom of last post. If you need any help anyway reply on this forum. Thanks to the author of this post which allowed me to get started and work out the asp solution
Hi there is there a way of
taking the picture- then straight away uploading it?
Hope to hear back, thanks in advance
Gemma
@ Matthew,
Hi Matthew, i have tried your code to upload image but we are not getting success. From application we are using same code as shown in the tutorial but at server side they are not getting any file in the request so can you please help us?
Here is the code for design in asp
Untitled Page
Cheers,
Dipen
@ Matthew,
Also Matthew, do we need to convert image data in base64 string or not?
Can someone please give me the test-upload.php file?
@matthew,
well sorry for the late reply.. it seems your code doesn’t work too.. in the iphone it looks success (from debug) but in server.. i couldn’t find the specified file
Hi, I tried your method, but doesn’t work on my location. I can not find the uploaded file. By the way, do you have any ideas on video uploading ?
Hello Sir,
I was really happy on seeing your code for uploading images to the server through iPhone. It worked great. I was trying to upload audio and video files too. I added some code to upload video file. But i was stuck up in the middle. First thing in the simulator video files are not listed in the picker Controller. Secondly how to send the video files instead of imageData.
Hai,
I had found a way to list video files in the simulator PickerController. If i select the video file it is getting selected and file is ready to play. If i click the play button the video gets played in the simulator. But if i click on the Choose button the simulator goes on compressing the video file but not transferring control to didFinishPickingImage function. Can the compressing be avoided in the simulator and read the video content and sent to the server to store the video file.
Thanks
Jaibabu
I changed the buttons to a toolbar with two buttons, how can I hide the upload button as you do with the UIButton? I have tried a few other resources but I can’t find any that work…
All I did is change UIButton to UIBarButtonItem to work with the buttons.