Summary
I would like to use PowerShell to retrieve an image from the Windows clipboard, and save it to a file.
When I copy an image to the clipboard, from a web browser for example, I am able to retrieve a System.Windows.Interop.InteropBitmap
object.
Once I have this object, I need to save the object to disk.
Question: How can I accomplish this?
Add-Type -AssemblyName PresentationCore
$DataObject = [System.Windows.Clipboard]::GetDataObject()
$DataObject | Get-Member
CodePudding user response:
All credits goes to this answer, this is merely a PowerShell adaptation of that code.
The code consists in 2 functions, one that outputs the InteropBitmap
instance of the image in our clipboard and the other function that receives this object from the pipeline and outputs it to a file. The Set-ClipboardImage
function can output using 3 different Encoders, you can add more if needed. See System.Windows.Media.Imaging
Namespace for details.
These functions are tested and compatible with Windows PowerShell 5.1 and PowerShell Core. I do not know if this can or will work in prior versions.
using namespace System.Windows
using namespace System.Windows.Media.Imaging
using namespace System.IO
using namespace System.Windows.Interop
Add-Type -AssemblyName PresentationCore
function Get-ClipboardImage {
$image = [Clipboard]::GetDataObject().GetImage()
do {
Start-Sleep -Milliseconds 200
$downloading = $image.IsDownloading
} while($downloading)
$image
}
function Set-ClipboardImage {
[cmdletbinding()]
param(
[Parameter(Mandatory)]
[ValidateScript({
if(Test-Path (Split-Path $_)) {
return $true
}
throw [ArgumentException]::new(
'Destination folder does not exist.', 'Destination'
)
})]
[string] $Destination,
[Parameter(Mandatory, ValueFromPipeline, DontShow)]
[InteropBitmap] $InputObject,
[Parameter()]
[ValidateSet('Png', 'Bmp', 'Jpeg')]
[string] $Encoding = 'Png'
)
end {
try {
$Destination = $PSCmdlet.GetUnresolvedProviderPathFromPSPath($Destination)
$encoder = switch($Encoding) {
Png { [PngBitmapEncoder]::new(); break }
Bmp { [BmpBitmapEncoder]::new(); break }
Jpeg { [JpegBitmapEncoder]::new() }
}
$fs = [File]::Create($Destination)
$encoder.Frames.Add([BitmapFrame]::Create($InputObject))
$encoder.Save($fs)
}
catch {
$PSCmdlet.WriteError($_)
}
finally {
$fs.ForEach('Dispose')
}
}
}
Get-ClipboardImage | Set-ClipboardImage -Destination .\test.jpg -Encoding Jpeg