views:

1107

answers:

5

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: http://i.imgur.com/gFsUY.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: http://imgur.com/sVH61.png

I wonder what encoding I should use. :S

A: 

Try changing :-

"application/x-www-form-urlencoded"

to

"multipart/form-data"
Paul Alan Taylor
Now, I recieve an error: "Error. No image was sent."
Sergio Tapia
+1  A: 

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
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
maybe you should ask to your API provider, or your current image is broken, or try to upload a JPEG image
Rubens Farias
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
what do you got as response?
Rubens Farias
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
Try to use Encoding.UTF8 instead Encoding.ASCII
Rubens Farias
Still getting the same image type: http://i.imgur.com/jgGty.jpg
Sergio Tapia
try to upload a smaller image (<30k)
Rubens Farias
"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
FileInfo fi = new FileInfo(path); byte[] content = new byte[(int)fi.Length]; new FileStream(path, FileMode.Open).Read(content, 0, content.Length);
Rubens Farias
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
A: 

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
Why the downvote?
feroze
+1  A: 

You should correctly form a multipart POST request. See an example here: http://stackoverflow.com/questions/566462/upload-files-with-httpwebrequest-multipart-form-data

VladV
Can clever -1ers please give a justification? +1ing to balance.
Ruben Bartelink
A: 

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