3

Here is the working code in Python (using cURL):

#!/usr/bin/python

import pycurl

c = pycurl.Curl()
values = [
          ("key", "YOUR_API_KEY"),
          ("image", (c.FORM_FILE, "file.png"))]
# OR:     ("image", "http://example.com/example.jpg"))]
# OR:     ("image", "BASE64_ENCODED_STRING"))]

c.setopt(c.URL, "http://imgur.com/api/upload.xml")
c.setopt(c.HTTPPOST, values)

c.perform()
c.close()

Here's what I have in C#:

public void UploadImage()
    {
        //I think this line is doing something wrong.
        //byte[] x = File.ReadAllBytes(@"C:\Users\Sergio\documents\visual studio 2010\Projects\WpfApplication1\WpfApplication1\Test\hotness2.jpg");

        //If I do it like this, using a direct URL everything works fine.
        string parameters = @"key=1b9189df79bf3f8dff2125c22834210903&image=http://static.reddit.com/reddit.com.header.png"; //Convert.ToBase64String(x);
        WebRequest webRequest = WebRequest.Create(new Uri("http://imgur.com/api/upload"));

        webRequest.ContentType = "application/x-www-form-urlencoded";
        webRequest.Method = "POST";
        byte[] bytes = Encoding.ASCII.GetBytes(parameters);

        Stream os = null;
        try
        { // send the Post
            webRequest.ContentLength = bytes.Length;   //Count bytes to send
            os = webRequest.GetRequestStream();
            os.Write(bytes, 0, bytes.Length);         //Send it
        }
        catch (WebException ex)
        {
            MessageBox.Show(ex.Message, "HttpPost: Request error");

        }
        finally
        {
            if (os != null)
            {
                os.Close();
            }
        }

        try
        { // get the response
            WebResponse webResponse = webRequest.GetResponse();

            StreamReader sr = new StreamReader(webResponse.GetResponseStream());
            MessageBox.Show(sr.ReadToEnd().Trim());
        }
        catch (WebException ex)
        {
            MessageBox.Show(ex.Message, "HttpPost: Response error");                  
        }            

    }

Now, the things I noticed is that when I changed my API key in the parameters string to "239231" or whatever number, the response I got was: "Invalid API key." So I think something must be working right.

I placed my correct API key and now I get a different response: "Invalid image format. Try uploading a JPEG image."

The service I'm using accepts almost every image format, so I am 100% certain the error is in the way I'm sending the file. Can anyone shed some light?

EDIT!!!

It turns out when I upload a JPG image I get that gray box thing. If I upload a big jpg image I don't get anything. For example: https://i.stack.imgur.com/8Y4uB.jpg

When I upload PNG's, the image uploaded doesn't even show.

I'm certain the issue is the encoding. What can I do?

EDIT 2!!!

Now I'm 100% certain that the problem lies in the first line of the method. The File.ReadAllBytes() must be doing something wrong. If I upload a URL file, every works peachy: https://i.stack.imgur.com/clcmZ.png

I wonder what encoding I should use. :S

Sergio Tapia
  • 40,006
  • 76
  • 183
  • 254
  • Try using a tool such as Fiddler to see how the data is POSTed, when the code executes from Python. And, see how the request is sent alongwith data when done from .net. That should help you find the difference & fix the later. – shahkalpesh Jan 12 '10 at 05:42

6 Answers6

3

Try this:

string file = @"C:\Users\Sergio\documents\visual studio 2010\Projects\WpfApplication1\WpfApplication1\Test\Avatar.png";
string parameters = @"key=1df918979bf3f8dff2125c22834210903&image=" +
    Convert.ToBase64String(File.ReadAllBytes(file));
Rubens Farias
  • 57,174
  • 8
  • 131
  • 162
  • This worked, somewhat. I think I'm sending the file before I complete reading all the bytes because I recieve this image: http://i.imgur.com/hXIfq.jpg – Sergio Tapia Jan 11 '10 at 18:51
  • maybe you should ask to your API provider, or your current image is broken, or try to upload a JPEG image – Rubens Farias Jan 11 '10 at 18:58
  • I don't know what's going wrong with the upload. Check this image out: http://i.imgur.com/y0WVP.jpg If you notice, the top has a bit of image, maybe I'm closing the connection too soon? How can I check this? – Sergio Tapia Jan 11 '10 at 18:59
  • I get a response OK, which is the expected response and it even gives me the link of the uplaoded image. I think the problem is in the encoding of the image. :S – Sergio Tapia Jan 11 '10 at 19:03
  • Try to use Encoding.UTF8 instead Encoding.ASCII – Rubens Farias Jan 11 '10 at 19:07
  • try to upload a smaller image (<30k) – Rubens Farias Jan 11 '10 at 19:29
  • "Cannot display image because it contains errors" - When uploading a very small image. Rubens, do you know a different way to read the bytes of a file other than File.ReadAllBytes()? I'm certain that is causing the issue because if I don't use that and upload a web image, it works perfectly. – Sergio Tapia Jan 11 '10 at 19:34
  • 1
    FileInfo fi = new FileInfo(path); byte[] content = new byte[(int)fi.Length]; new FileStream(path, FileMode.Open).Read(content, 0, content.Length); – Rubens Farias Jan 11 '10 at 19:41
  • btw, web images doesnt involves byte[] encoding; I suggest you to finish this question and to start another one and/or ask your API provider for directions – Rubens Farias Jan 11 '10 at 19:44
3

You should correctly form a multipart POST request. See an example here: Upload files with HTTPWebrequest (multipart/form-data)

Community
  • 1
  • 1
VladV
  • 10,093
  • 3
  • 32
  • 48
1

Read image posted by in API

public IHttpActionResult UpdatePhysicianImage(HttpRequestMessage request)
    {
        try
        {
            var form = HttpContext.Current.Request.Form;
            var model = JsonConvert.DeserializeObject<UserPic>(form["json"].ToString());
            bool istoken = _appdevice.GettokenID(model.DeviceId);
            if (!istoken)
            {
                statuscode = 0;
                message = ErrorMessage.TockenNotvalid;
                goto invalidtoken;
            }
            HttpResponseMessage result = null;
            var httpRequest = HttpContext.Current.Request;
            if (httpRequest.Files.Count > 0)
            {
                var docfiles = new List<string>();
                foreach (string file in httpRequest.Files)
                {
                    var postedFile = httpRequest.Files[file];
                    // var filePath = uploadPath + postedFile.FileName;
                    //  string fileUrl = Utility.AbsolutePath("~/Data/User/" + model.UserId.ToString());
                    string fileUrl = Utility.AbsolutePath("~/" + Utility.UserDataFolder(model.UserId, "Document"));
                    if (!Directory.Exists(fileUrl))
                    {
                        Directory.CreateDirectory(fileUrl);
                        Directory.CreateDirectory(fileUrl + "\\" + "Document");
                        Directory.CreateDirectory(fileUrl + "\\" + "License");
                        Directory.CreateDirectory(fileUrl + "\\" + "Profile");
                    }
                    string imageUrl = postedFile.FileName;
                    string naviPath = Utility.ProfileImagePath(model.UserId, imageUrl);
                    var path = Utility.AbsolutePath("~/" + naviPath);
                    postedFile.SaveAs(path);
                    docfiles.Add(path);
                    if (model.RoleId == 2)
                    {
                        var doctorEntity = _doctorProfile.GetNameVideoChat(model.UserId);
                        doctorEntity.ProfileImagePath = naviPath;
                        _doctorProfile.UpdateDoctorUpdProfile(doctorEntity);
                    }
                    else
                    {
                        var patientEntity = _PatientProfile.GetPatientByUserProfileId(model.UserId);
                        patientEntity.TumbImagePath = naviPath;
                        _PatientProfile.UpdatePatient(patientEntity);
                    }
                }
                result = Request.CreateResponse(HttpStatusCode.Created, docfiles);
            }
            else
            {
                result = Request.CreateResponse(HttpStatusCode.BadRequest);
            }
        }
        catch (Exception e)
        {
            statuscode = 0;
            message = "Error" + e.Message;
        }
    invalidtoken:
        return Json(modeldata.GetData(statuscode, message));
    }
smottt
  • 3,272
  • 11
  • 37
  • 44
Rajesh Kumar
  • 602
  • 6
  • 20
0

Try changing :-

"application/x-www-form-urlencoded"

to

"multipart/form-data"
Paul Alan Taylor
  • 10,474
  • 1
  • 26
  • 42
0

Try adding the content-type for the jpg into your multipart boundary.

See this uRL for examples (at the end)

http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.2

feroze
  • 7,380
  • 7
  • 40
  • 57
-1

Shot in the dark, but maybe create an instance of Image, save the file to a Stream and use that to read the bytes into an array then upload it.

As in:

Image i = System.Drawing.Image.FromFile("wut.jpg");
Stream stm = new Stream();
System.Drawing.Imaging.Encoder myEncoder = System.Drawing.Imaging.Encoder.Quality;
System.Drawing.Imaging.EncoderParameters paramz = new System.Drawing.Imaging.EncoderParameters(1);
myEncoderParameter = new EncoderParameter(myEncoder, 100L);
paramz.Param[0] = myEncoderParameter;
i.Save(stm, System.Drawing.Imaging.ImageFormat.Jpeg, paramz);
/* I'm lazy: code for reading Stream into byte[] here */
cgd
  • 1