Problem/Overview




One of the toughest things in terms of hard to work with APIs is the Imgur API, it is very uh, well it isn't necessarily made for .NET - Most of my projects I work on are in VB.NET, so I need to be able to do certain things. One of my goals was in my Browser Project was to have a ScreenCapture program, with automatic upload to Imgur AND copy the link, or insert into a TextBox- And with that in mind, along of the help of a friend, as well as the Web Extensions Library, it is possible to do just that. Yes, there are older examples of this, but they are outdated, and no longer valid or just plainly bad examples.

One of the things, most of the examples in C# excluded was how to get the link to the image you just uploaded. While the code on how to upload is a bit older, and there seems to be nothing on the documentation, between myself and the friend, we managed to get it working.

License

All Source Code is Licensed under the MIT License - The license can be found in the Respo for this CodeBank Entry.

Official Respo



Tutorial

Min. Requirements:
  • .NET Framework 4.0 or Newer
  • VS 15 or newer



After this tutorial your new ScreenCapture program will:


  • Save to a Certain Folder you create.
  • Automatic Saving
  • Uploading to Imgur
  • Getting Link to your Imgur Upload.





Start off by opening a new project - Add a reference to the System.Web.Extensions - Add 2 Buttons, "Capture" & "Save"

To Capture an Image, you can do this by making a Bitmap of your Screen, you can edit this, and even make a snipping tool to only capture certain areas, for the sake of this tutorial we will be doing a full screen capture.


Capture:


Code:
   Me.Opacity = 0
        Dim area As Rectangle
        Dim capture As System.Drawing.Bitmap
        Dim graph As Graphics
        area = Screen.PrimaryScreen.WorkingArea
        capture = New System.Drawing.Bitmap(area.Width, area.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb)
        graph = Graphics.FromImage(capture)
        graph.CopyFromScreen(area.X, area.Y, 0, 0, area.Size, CopyPixelOperation.SourceCopy)
        PictureBox1.Image = capture
You probably want to show the form once the capture has been completed, so add this in:

Code:
  Public Sub Capture_Complete()
        Me.Opacity = 1


    End Sub
Be sure to call it in the capture part.


________________________________________________________________________

With the AutoSaving capabilities, you can leave out the Save Button if you wish, but some may like to manually rename or Resave the file.


Save:


Code:
    Dim save As New SaveFileDialog
        Try
            save.Title = "Save File"
            save.FileName = "Screenshot"
            save.Filter = "Bitmap Image (.bmp)|*.bmp|JPEG Image (.jpeg)|*.jpeg|Png Image (.png)|*.png|Tiff Image (.tiff)|*.tiff"
            If save.ShowDialog = Windows.Forms.DialogResult.OK Then
                PictureBox1.Image.Save(save.FileName, Drawing.Imaging.ImageFormat.Png)
            End If

        Catch ex As Exception


AutoSaving


One of the things that can be done with Autosaving, is either save it when you capture, or save it after a few seconds after. You can even add more autosaving abilities.

You can also add an Option to users to change the file extension. Change the ".png" to something like My.settings.Extension - so that you can save what format the user wants.

Imgur will only allow a certain size, as well as certain extensions, keep that in mind when giving users that ability.

You need to make sure you add the folder "Example" in your Photos in order to make this example to work, failure to do this will result in a invalid file exception.

You can also observe that I am saving the file, using the current date and time.

Code:
    Public Sub AutoSave()

        Dim strfilename = My.Computer.FileSystem.SpecialDirectories.MyPictures & "/Example/" & "ScreenShot-" & Now.ToString("ddd_dd_MM_yyyy_hh_mm_ss") & ".png"

      
        Me.PictureBox1.Image.Save(IO.Path.Combine(strfilename))
        Me.Text = "AutoSaved To: " & strfilename


    End Sub
If you want to Auto-Save, you can by calling it during the capture or on a timer.




Posting to Imgur



To Post to Imgur, as well as get the link to either your clipboard or to a Textbox, you first create a webrequest, then parse the response, and get the Link to the image.

Getting a link to the image will not show it on the normal Imgur website instead this is a direct link, all uploads using this process is anonymous you can add abilities to be under user's personal accounts.

You also need a API key, to do this - you can get the Client ID - over on the Imgur API site.

Code:
 Public Class ImgurImageData
        Public Property link() As String
    End Class
    Public Class ImgurAPI
        Public Property data() As ImgurImageData
    End Class

    Public Shared Function PostToImgur(ByVal imagFilePath As String, ByVal apiKey As String) As String
        Dim imageData As Byte()
        Dim fileStream As FileStream = File.OpenRead(imagFilePath)
        imageData = New Byte(fileStream.Length - 1) {}
        fileStream.Read(imageData, 0, imageData.Length)
        fileStream.Close()
        Const MAX_URI_LENGTH As Integer = 32766
        Dim base64img As String = System.Convert.ToBase64String(imageData)
        Dim sb As StringBuilder = New StringBuilder()
        Dim i As Integer = 0

        While i < base64img.Length
            sb.Append(Uri.EscapeDataString(base64img.Substring(i, Math.Min(MAX_URI_LENGTH, base64img.Length - i))))
            i += MAX_URI_LENGTH
        End While

        Dim uploadRequestString As String = "key=" & apiKey & "&title=" & "imageTitle" & "&caption=" & "img" & "&image=" & sb.ToString()
        Dim request As HttpWebRequest = CType(WebRequest.Create("https://api.imgur.com/3/image"), HttpWebRequest)
        request.Method = "POST"
        request.ContentType = "application/x-www-form-urlencoded"
        request.ServicePoint.Expect100Continue = False
        request.Headers("Authorization") = "Client-ID PlaceHere"
        Dim streamWriter As StreamWriter = New StreamWriter(request.GetRequestStream())
        streamWriter.Write(uploadRequestString)
        streamWriter.Close()
        Dim response As WebResponse = request.GetResponse()
        Dim responseStream As Stream = response.GetResponseStream()
        Dim responseReader As StreamReader = New StreamReader(responseStream)

        Dim jss As New JavaScriptSerializer()
        Dim image As ImgurAPI = jss.Deserialize(Of ImgurAPI)(responseReader.ReadToEnd())

        Dim url As String = image.data.link

        Clipboard.Clear()
        Clipboard.SetText(url)
        'TextBox1.Text = url
    End Function
Now, to upload, simply add the following in autosave - As it will take the file and upload it dynamically when saving.

Code:
 PostToImgur(strfilename, "ClientID")


If you got questions or issues, please do not post them here, rather in the official Respo of this CodeBank Entry.

Thank you.