• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
  • Help Room /
avatar image
Question by x70x · Mar 07, 2016 at 01:52 PM · networkingimageuploadwwwform

How can I upload a screenshot directly to Imgur?

I have been trying to follow Imgur's api for uploading images

So far I have been able to get it to properly recognize my Client ID. I know that I am getting through, but I still get a 400 error, which according to Imgur's documentation means

Status Code: 400 This error indicates that a required parameter is missing or a parameter has a value that is out of bounds or otherwise incorrect. This status code is also returned when image uploads fail due to images that are corrupt or do not meet the format requirements.

This is the code I am using:

 IEnumerator AppScreenshot()
     {
         Application.CaptureScreenshot(Application.persistentDataPath + "/screenshot.png");
 
         WWW www = new WWW(Application.persistentDataPath + "/screenshot.png");
         yield return www;
 
         WWWForm form = new WWWForm();
         form.AddBinaryData("image", www.bytes);
         Dictionary <string, string> headers = form.headers;
         headers["Authorization"] = "Client-ID <client_id>";
         byte[] rawData = form.data;
 
         WWW w = new WWW("https://api.imgur.com/3/image", rawData, headers);
         yield return w;
         if (!string.IsNullOrEmpty(w.error))
         {
             print(w.error);
         }
         else
         {
             print(w.responseHeaders["link"]);
         }
     }

The WWW class will not allow me to pass the form directly without converting it to raw bytes first. Is this part of the problem? Why is imgur seemingly unable to accept the image file?

Comment
MrLucid72
UnitySeller

People who like this

2 Show 0
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

  • Sort: 
avatar image

Answer by x70x · Mar 07, 2016 at 07:49 PM

Ok, so after a LOT of google-fu I managed to find a working solution. I had to abandon the use of the WWW class and resort to System.Net instead. Then I ran into a security certificate problem so I found a workaround for that as well. Below is the fully working code for grabbing a screenshot and uploading it to imgur.

 IEnumerator AppScreenshotUpload()
     {
         yield return new WaitForEndOfFrame();
         Application.CaptureScreenshot(Application.persistentDataPath + filename);
 
         //Make sure that the file save properly
         float startTime = Time.time;
         while (false == File.Exists(Application.persistentDataPath + filename))
         {
             if (Time.time - startTime > 5.0f)
             {
                 yield break;
             }
             yield return null;
         }
 
         //Read the saved file back into bytes
         byte[] rawImage = File.ReadAllBytes(Application.persistentDataPath + filename);
 
         //Before we try uploading it to Imgur we need a Server Certificate Validation Callback
         ServicePointManager.ServerCertificateValidationCallback = MyRemoteCertificateValidationCallback;
     
         //Attempt to upload the image
         using (var w = new WebClient())
         {
             string clientID = "put your Client ID here";
             w.Headers.Add("Authorization", "Client-ID " + clientID);
             var values = new NameValueCollection
             {
                 { "image", Convert.ToBase64String(rawImage) },
                 { "type", "base64" },
             };
 
             byte[] response = w.UploadValues("https://api.imgur.com/3/image.xml", values);
 
             Debug.Log(XDocument.Load(new MemoryStream(response)));
         }
     }
 
     public bool MyRemoteCertificateValidationCallback(System.Object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
     {
         bool isOk = true;
         // If there are errors in the certificate chain, look at each error to determine the cause.
         if (sslPolicyErrors != SslPolicyErrors.None)
         {
             for (int i = 0; i < chain.ChainStatus.Length; i++)
             {
                 if (chain.ChainStatus[i].Status != X509ChainStatusFlags.RevocationStatusUnknown)
                 {
                     chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain;
                     chain.ChainPolicy.RevocationMode = X509RevocationMode.Online;
                     chain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 1, 0);
                     chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllFlags;
                     bool chainIsValid = chain.Build((X509Certificate2)certificate);
                     if (!chainIsValid)
                     {
                         isOk = false;
                     }
                 }
             }
         }
         return isOk;
     }

Currently this creates a lot of screenshots in the persistentDataPath location so you might want to just overwrite a single file instead to prevent that. You can get the url of the uploaded image from the MemoryStream(response). In this case you can read it in the Debug.Log after it's successful. You'll have to parse it to grab the URL at runtime.

Comment
God-at-play
MrLucid72
UnitySeller
shaojim12

People who like this

4 Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image God-at-play · Mar 08, 2016 at 12:33 AM 0
Share

Maybe it doesn't matter at this point, but FWIW I see several differences here from the WWW version: the URL has an xml extension (likely doesn't matter), explicitly encoding in base64, and also including the type in your submission.

avatar image

Answer by UnitySeller · Feb 04, 2018 at 03:57 AM

YOUR CODE WORK PERFECT

Also add this :

using UnityEngine; using UnityEngine.Networking; using System.Collections; using System.Security.Cryptography.X509Certificates; using System.Net.Security; using System.Collections.Specialized; using System.Net; using System; using System.Xml.Linq; using System.IO;

To get link directly replace " Debug.Log " line with this :

XDocument xDoc = XDocument.Load (new MemoryStream (response));

string MyPicUrl;

MyPicUrl = xDoc.Element("data").Element("link").Value;

Comment
shaojim12

People who like this

1 Show 0 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Unity Answers is in Read-Only mode

Unity Answers content will be migrated to a new Community platform and we are aiming to launch a public beta by June 9. Please note, Unity Answers is now in read-only so we can prepare for the final data migration.

For more information and updates, please read our full announcement thread in the Unity Forum.

Follow this Question

Answers Answers and Comments

6 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Share screenshot on FB without SDK? 1 Answer

Upload image from IOS gallery show no search result but works find in Android 0 Answers

Unity Android I have written .csv into application.persistantdatapath and i cannot upload it from android 0 Answers

Does anyone know why this simple block of code is more efficient? 1 Answer

Getting "500 Internal Server Error" while uploading Image to server. 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges