2

I want to use the Powershell to send the image in clipboard into figure bed(such as http://stackoverflow.com/upload/image).If I'm in Mathematica,I can get the image in clipboard,then use this code send the image into picture bed

URLRead[HTTPRequest["http://stackoverflow.com/upload/image", <|
   "Body" -> {"image" -> imageInClipboard}|>], "Body"]

But this method is poor efficiency. So I hope do this just by Powershell.

$img=Get-Clipboard -Format image
Invoke-RestMethod -Uri http://stackoverflow.com/upload/image -ContentType "image/png" -Body $img

But it don't work..And a markdown result like ![](imagelink) is expected.Anydody can give me a hand?

  • powershell 3 and up, you should be able to use invoke-restmethod or invoke-webrequest, see this answer for an example stackoverflow.com/a/36269506/1123692 – wmz Jul 25 '17 at 19:30
  • @wmz That method in your link is try to upload a image in local disk,but I want to upload a image in clipboard – yode Sep 19 '17 at 13:55
  • 1
    @Ben N Hi,I have to ping a guru to here.This problem hinder me too long..Help please.. – yode Sep 20 '17 at 12:41
2
+50

I wrote this script for you:

$img = Get-Clipboard -Format Image
If (-not $img) {Throw 'No image on the clipboard'}
$ms = New-Object System.IO.MemoryStream
$img.Save($ms, [System.Drawing.Imaging.ImageFormat]::Png)
$ms.Position = 0
Add-Type -AssemblyName System.Net.Http
$httpClientHandler = New-Object System.Net.Http.HttpClientHandler
$httpClient = New-Object System.Net.Http.HttpClient $httpClientHandler
$contentDispositionHeaderValue = New-Object System.Net.Http.Headers.ContentDispositionHeaderValue "form-data"
$contentDispositionHeaderValue.Name = "file"
$contentDispositionHeaderValue.FileName = 'image.png'
$streamContent = New-Object System.Net.Http.StreamContent $ms
$streamContent.Headers.ContentDisposition = $contentDispositionHeaderValue
$streamContent.Headers.ContentType = New-Object System.Net.Http.Headers.MediaTypeHeaderValue 'image/png'
$content = New-Object System.Net.Http.MultipartFormDataContent
$content.Add($streamContent)
$response = $httpClient.PostAsync('https://stackoverflow.com/upload/image?https=true', $content).Result
$response.Content.ReadAsStringAsync().Result -match '"(.*)"' | Out-Null
"![]($($matches[1]))"

First, it converts the image on the clipboard to PNG. Then it takes advantage of some .NET web utility classes to get the multipart/form-data structure set up just right - this section is adapted from Mario Majčica's blog post. Once that's all finagled, it makes the POST request. Finally, it uses regex to parse the small resulting HTML document to extract the URL of the newly uploaded image, which it prints to the console. If you'd like to copy the Markdown fragment directly to the clipboard, tack on | scb to the last line.

To run the script, save it as a .ps1 file, e.g. seimage.ps1. If you haven't already, follow the instructions in the Enabling Scripts section of the PowerShell tag wiki. Then you can open a PowerShell prompt in the containing folder and execute it:

.\seimage.ps1
  • Hi, Mr. guru. I make some tunning in your code.If you are available. Please give me response? – yode Sep 21 '17 at 6:06
1

I just compile the code here for reading after some guidence from Ben N

$img = Get-Clipboard -Format Image
If (-not $img) {
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$objNotifyIcon = New-Object System.Windows.Forms.NotifyIcon 
$objNotifyIcon.Icon = [System.Drawing.SystemIcons]::Warning
$objNotifyIcon.BalloonTipIcon = "Error" 
$objNotifyIcon.BalloonTipText = 'No image on the clipboard' 
$objNotifyIcon.BalloonTipTitle = "File Not Found"
$objNotifyIcon.Visible = $True 
$objNotifyIcon.ShowBalloonTip(10000)
}
Else{
    $ms = New-Object System.IO.MemoryStream
    $img.Save($ms, [System.Drawing.Imaging.ImageFormat]::Png)
    $ms.Position = 0
    Add-Type -AssemblyName System.Net.Http
    $httpClientHandler = New-Object System.Net.Http.HttpClientHandler
    $httpClient = New-Object System.Net.Http.HttpClient $httpClientHandler
    $contentDispositionHeaderValue = New-Object System.Net.Http.Headers.ContentDispositionHeaderValue "form-data"
    $contentDispositionHeaderValue.Name = "file"
    $contentDispositionHeaderValue.FileName = 'image.png'
    $streamContent = New-Object System.Net.Http.StreamContent $ms
    $streamContent.Headers.ContentDisposition = $contentDispositionHeaderValue
    $streamContent.Headers.ContentType = New-Object System.Net.Http.Headers.MediaTypeHeaderValue 'image/png'
    $content = New-Object System.Net.Http.MultipartFormDataContent
    $content.Add($streamContent)
    $response = $httpClient.PostAsync('https://stackoverflow.com/upload/image?https=true', $content).Result
    $response.Content.ReadAsStringAsync().Result -match '"(.*)"' | Out-Null
    if ($args -eq "linkonly"){
        Set-Clipboard $matches[1]   
        }
    else{
        Set-Clipboard "![]($($matches[1]))"
    }
}
  • If you would prefer a GUI error message, you can do Add-Type -AssemblyName System.Windows.Forms and then [System.Windows.Forms.MessageBox]::Show('Error text here'). Regarding the exported file, the clipboard is only saved to a memory stream, which will be destroyed as soon as PowerShell exits. The "image.png" is only what the script tells the server that the filename is; I included that to match the Stack Exchange image upload feature as exactly as possible. No extra file is created on your disk. – Ben N Sep 21 '17 at 13:34
  • @BenN NoNoNo,I don't like gui error message.You have to make a extra click..I like the tray message.But I don't know why I have to specify a .ico file..And the .ico image will not apear in my tray.. – yode Sep 21 '17 at 13:45
  • Ah, the Icon property expects an icon object (rather than a file path). You can get one of those with New-Object System.Drawing.Icon 'C:\path\to\iconfile.ico'. – Ben N Sep 21 '17 at 13:48
  • @BenN I'm very sorry,I don't know how to use your New-Object System.Drawing.Icon 'C:\path\to\iconfile.ico' in my code.Could you help to edit my answerr? – yode Sep 21 '17 at 13:55
  • I adjusted the icon-related line, though I don't have an ICO file to test with. If you don't need an icon, I think it's fine to leave out the setting of the Icon property. – Ben N Sep 21 '17 at 14:01

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.