target
Recently learning to write documents with MarkDown, I hate passing pictures.Prepare to build your own wheel with PowerShell, but also search ahead and find a lot of Big Brother's documents.
The whole process to do is
- Copy Clipboard Picture with Mouse
- Enter program processing logic
- Processing clipboard pictures, saving cost local files (png or jpg)
- Upload to a map bed to get a connection to the map bed
- Construct the link to the map bed into the format required by MarkDown and stuff it back into the clipboard.
- Go back to the MarkDown editor and clip directly.
The goal is phase 2 content, completely scripted.
RealizationPowerShell is easy to create and modify files. The key point here is to use the.net method to manipulate pictures directly.
$img = [Windows.Clipboard]::GetImage()
Based on this keyword, let's take a look
Clipboard Class And there's a specific way to do that
Not only can you get, but also set here. Not only pictures, but also text and audio can be operated. It is a complete set of schemes for the clipboard.The original output format is PNG, I want to try how to output JPG
picture
Just now we have finalized the contents of the clipboard. Next, we need to save the clipboard data as a picture.
Code
This can be learned
ImageCodecInfo.GetImageEncoders Method
Clipboard Save PNG
#Clipboard saves png directly Add-Type -Assembly PresentationCore $img = [Windows.Clipboard]::GetImage() if ($null -eq $img ) { Write-Host "Clipboard no map" Exit } $fcb = New-Object Windows.Media.Imaging.FormatConvertedBitmap($img, [Windows.Media.PixelFormats]::Rgb24, $null, 0) $filename = ((Get-Date -f s) -replace '[-T:]', '') $file = "c:/img/.jpg" -f $filename Write-Host ("`n Find Pictures. x Pixels, saved to`n" -f $img.PixelWidth, $img.PixelHeight, $file) $stream = [IO.File]::Open($file, "OpenOrCreate") $encoder = New-Object Windows.Media.Imaging.PngBitmapEncoder $encoder.Frames.Add([Windows.Media.Imaging.BitmapFrame]::Create($fcb)) $encoder.Save($stream) # $stream.Dispose()
Various styles, not limited to PowerShell
{ Bitmap bmp1 = new Bitmap(typeof(Button), "Button.bmp"); bmp1.Save(@"c:\button.png", ImageFormat.Png); } #Store pictures relatively easily #https://stackoverflow.com/questions/41665/bmp-to-jpg-png-in-c-sharp #Advanced Storage Pictures #https://stackoverflow.com/questions/1484759/quality-of-a-saved-jpg-in-c-sharp #Official examples #https://docs.microsoft.com/en-us/dotnet/api/system.drawing.imaging.imagecodecinfo.getimageencoders?view=netframework-4.8
PNG Conversion JPG
A trick used here is Add-Type-AssemblyName system.drawing
Add-Type -AssemblyName system.drawing $Source="C:\img\tt2.png" $imageFormat = "System.Drawing.Imaging.ImageFormat" -as [type] $image = [drawing.image]::FromFile($Source) # Create a new image $NewImage = [System.Drawing.Bitmap]::new($Image.Width,$Image.Height) $NewImage.SetResolution($Image.HorizontalResolution,$Image.VerticalResolution) #Add graphics from new images $Graphics = [System.Drawing.Graphics]::FromImage($NewImage) $Graphics.Clear([System.Drawing.Color]::White) # Set the color to white $Graphics.DrawImageUnscaled($image,0,0) # Add the contents of $image #storage $NewImage.Save("c:\img\vvv.jpg",$imageFormat::Jpeg)
Read an IMG, resize, and write
Add-Type -AssemblyName System.Drawing $img = New-Object System.Drawing.Bitmap(96, 96) ([System.Drawing.Graphics]::FromImage($img)).DrawImage([System.Drawing.Image]::FromFile((Get-Item C:\img\20191104135629.jpg)), 0, 0, 128, 128) $jpegCodecInfo = [System.Drawing.Imaging.ImageCodecInfo]::GetImageEncoders() | where {$_.MimeType -eq 'image/jpeg'} $encoderParams = New-Object System.Drawing.Imaging.EncoderParameters(1) $encoderParams.Param[0] = New-Object System.Drawing.Imaging.EncoderParameter([System.Drawing.Imaging.Encoder]::Quality, 90) $img.Save("c:\img\bouska2.jpg", $jpegCodecInfo, $encoderParams) $img.Dispose()
Transfer files to github using GIT
github is a money-Free computer bed that allows you to upload and download files using git.
- Configure local git
git config --global user.name "User name" git config --global user.email "email" cd ~/.ssh ssh-keygen -t rsa -C "email" #This step above is to generate a certificate to communicate with github.
- Configure github receive key
open Here , find SSH and GPG keys in the right menu bar, select new SSH key, enter title, the contents of the key below is the native ssh key, which is the public key just generated, paste the contents of id_rsa.pub directly, and click add SSH key below to complete.
- Copy Key
Enter the command cat id_rsa.pub, and it will come out like the following, and copy it out, which is the key
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDRyubAWD7PfF+baIYAYVpdtTag7YZYdmCNz2mkoMjxkP6aN5C/Rnxxxxxxxxxxxxxxxxxxxxx5sSNV42co5S4Tc5W3eBB9bPBIoObqZ/g8JkCVrEIgUXTO1rn9p7h5erQ0/TcC/tIQ+HVxVx+mV7Y/wcYY05+Bbm8Cv60= [email protected]
- Create directory locally C:\gitupdate
git remote add origin https://github.com/kukisama/kukisama.github.io Add a local directory
git add c:/gitupdate/picupdate/tt.txt Upload local file
Git commit-m "for a description"
git push origin master pull back
git pull origin master upload
The preconditions are almost ready, so you can see the full code.
The clipboard saves the png directly, passes it to github, and references the address of the github page
#Clipboard saves png directly Add-Type -Assembly PresentationCore $img = [Windows.Clipboard]::GetImage() if ($null -eq $img ) { Write-Host "Clipboard no map" } $rootpath="C:/kukisama.github.io/picupdate/" $fcb = New-Object Windows.Media.Imaging.FormatConvertedBitmap($img, [Windows.Media.PixelFormats]::Rgb24, $null, 0) $filename = ((Get-Date -f s) -replace '[-T:]', '') $file = "$rootpath.png" -f $filename Write-Host ("`n Find Pictures. x Pixels, saved to`n" -f $img.PixelWidth, $img.PixelHeight, $file) $stream = [IO.File]::Open($file, "OpenOrCreate") $encoder = New-Object Windows.Media.Imaging.PngBitmapEncoder $encoder.Frames.Add([Windows.Media.Imaging.BitmapFrame]::Create($fcb)) $encoder.Save($stream) $stream.Dispose() $rootpath="C:/kukisama.github.io/picupdate/" cd $rootpath cd .. $lastfile=(ls $rootpath |sort LastWriteTime -Descending)[0].name $MARKDOWNpic=New-Object System.Collections.ArrayList $MARKDOWNpic.add('![image](http://github.ny9s.com/picupdate/'+$lastfile+')')|out-null $MARKDOWNpic.Add(' ')|out-null $MARKDOWNpic|Set-Clipboard Write-Host "Pot-friends, now available in MarkDown Copy the text address in the editor" git add $rootpath$lastfile git commit -m $lastfile git push -u origin master|Out-Null -ErrorAction SilentlyContinue #git rm -r C:/kukisama.github.io/picupdate/
Spiritual Transition
Functional logic is almost finished, but all of a sudden I found such an article Shen Tie
When I read the post, this logic already exists in 2015...
Here's an original Lifeline, Set-Clipboard and Get-Clipboard
So it only takes two steps to save the file
$PNGfile=Get-Clipboard -Format Image $PNGfile.Save($file)
So the modified logic is like this
$PNGfile=Get-Clipboard -Format Image if ($PNGfile) { $rootpath="C:/kukisama.github.io/picupdate/" $internetURL="http://github.ny9s.com/picupdate/" $filename = ((Get-Date -f s) -replace '[-T:]', '') $file = "$rootpath.png" -f $filename $PNGfile.Save($file) cd $rootpath;cd .. $MARKDOWNpic=New-Object System.Collections.ArrayList #$MARKDOWNpic.add('![image]('+$interneturl+$filename+'.png'+')') #The above address is the github page address, but in fact, it refreshes very slowly, so I take the time address of the file directly $MARKDOWNpic.add('![image]('+'https://github.com/kukisama/kukisama.github.io/blob/master/picupdate/'+$filename+'.png'+'?raw=true)') $MARKDOWNpic.Add(' ') $MARKDOWNpic|Set-Clipboard Write-Host "Pot-friends, now available in MarkDown Copy the text address in the editor" git add $file git commit -m $filename git push }
antic
There's also a trick: for screen characters that are output to objects, you can first convert them to strings and then output them to the clipboard
dir | Out-String | Set-ClipboardUpload using FTP
The graph bed of github page is really unstable in China.The initial idea here is to use the best FTP to save your pictures and set up an FTP server yourself, assuming the name is xxx.ny9s.com
What you actually need to do for the corresponding web site, ny9s.com/pic, is pass the picture to FTP and generate the corresponding web-side string.Modify the script again.
Start with Ubuntu 16.04 Install ftp Server Go configure it
sudo apt-get install vsftpd Create user directory sudo mkdir picupdate Create user sudo useradd-d/var/www/html/picupdate-s/bin/bash uftp sudo mkdir picupdate sudo vi /etc/vsftpd.conf #Edit vsftpd.conf file userlist_deny=NO userlist_enable=YES #Users allowed to log on userlist_file=/etc/allowed_users seccomp_sandbox=NO #Default ftp download directory local_root=/home/uftp/ local_enable=YES #Set up file upload write_enable=YES #Use utf8 utf8_filesystem=YES Add users who are allowed to log on sudo gedit /etc/allowed_users Save after modifications, and then restart the service sudo /etc/init.d/vsftpd start sudo /etc/init.d/vsftpd stop sudo /etc/init.d/vsftpd restart If the flowers are in passive mode, Open xxx/vsftpd/vsftpd.conf and add at the end: pasv_enable=YES //Turn on PASV mode pasv_min_port=40000 //min port number pasv_max_port=40000 //max port number pasv_promiscuous=YES Permissions under reconfiguration sudo chown uftp:uftp /var/www/html/picupdate/FTP Upload File Logic
# create the FtpWebRequest and configure it $ftp = [System.Net.FtpWebRequest]::Create("ftp://localhost/me.png") $ftp = [System.Net.FtpWebRequest]$ftp $ftp.Method = [System.Net.WebRequestMethods+Ftp]::UploadFile $ftp.Credentials = new-object System.Net.NetworkCredential("anonymous","anonymous@localhost") $ftp.UseBinary = $true $ftp.UsePassive = $true # read in the file to upload as a byte array $content = [System.IO.File]::ReadAllBytes("C:\me.png") $ftp.ContentLength = $content.Length # get the request stream, and write the bytes into it $rs = $ftp.GetRequestStream() $rs.Write($content, 0, $content.Length) # be sure to clean up after ourselves $rs.Close() $rs.Dispose()sudo vi /etc/vsftpd.conf sudo vi /etc/services sudo /etc/init.d/vsftpd restart After vsftpd starts, the default ftp port is 21. Now I want to change the ftp port to 801, so that the user's upload and download will not be affected. 1. Edit the/etc/vsftpd/vsftpd.conf file and add this line to the configuration file: listen_port=801 2. Edit/etc/services file to include Change ftp 21/tcp to ftp 801/tcp Change ftp 21/udp to ftp 801/udp 3. Execute/etc/init.d/vsftpd restart to restart the vsftpd service.After the boot is complete, you can use the netstat-ntpl | grep vsftpd command to see the system implementation Listening vsftpd has port 801 4. Use lftp 192.168.0.1:801(192.168.0.1 is the address of the vsftpd server) so that you can access the ftp server. Open Firewall ufw enable Close Firewall ufw disable
However, the above question, although it seems that the steps should be detailed, is that the configuration of my environment failed...
Posh SSH
Spend a lot of time on FTP and start looking for solutions.After testing, the easiest way is to install the Posh-SSH module to upload and download files using SSH.This module is github Can be downloaded to.
You can also install it directly using Install-Module-Name Posh-SSH-RequiredVersion 2.0.2, which I think has the following advantages:
- The server only needs to open the SSH port, and this port can work as well as mapping to other ports without using 22.
- No active and passive mode, no accounts, no ports or anything like FTP
- The file is not big as a whole, only more than 2M, and only 1.7M after deleting the help file, whether it is downloaded directly or made into an offline package.
4. Big Brother's code is well encapsulated and only one command is needed to upload and download files.Writing on your own is almost the limit.
Code Examples
$cred=Get-Credential #Agree to KEY, download files remotely Get-SCPFile -ComputerName "ny9s.com" -Port 12121 -Credential $cred -RemoteFile "/home/kukisama/IOid.jpg" -LocalFile 'C:\img\ppp.jpg' -AcceptKey #upload Set-SCPFile -ComputerName "ny9s.com" -Port 12121 -Credential $cred -Remotepath "/home/kukisama" -LocalFile 'C:\img\ppp.jpg'
What modules can clean up
If installed online, the module will be located in
C:\Program Files\WindowsPowerShell\Modules\Posh-SSH If not, deleting it directly is equivalent to uninstalling.
The overall directory has 2.26MB and 500K help files. After testing, it found that deletion did not affect (en-US directory).
Password Encryption and Decryption Logic
In order to connect SSH silently, a password logic is used to place the required $cred encryption in a local folder, which is easier to use
#Step 1. Keep the password encrypted until c:\xxx.txt. $mysecret="xxxxxx" #Put your password here $mysecret|ConvertTo-SecureString -AsPlainText -Force |ConvertFrom-SecureString|Out-File C:\picupdate\pass.txt -Encoding utf8 #Step 2. Convert the ciphertext password to a format that the powershell can use $securestring=(Get-Content C:\picupdate\pass.txt).ToString() | ConvertTo-SecureString $ptr = [System.Runtime.InteropServices.Marshal]::SecureStringToGlobalAllocUnicode($secureString) $serverpass = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($ptr) $Password = ConvertTo-SecureString $serverpass -AsPlainText –Force #Step 3. Use $UserName = "admin" #Define Administrator Account Name $cred = New-Object System.Management.Automation.PSCredential($UserName,$Password)Overall code, PNG format
$PNGfile=Get-Clipboard -Format Image if ($PNGfile) {$start=Get-Date $rootpath="C:/picupdate/" $internetURL="http://ny9s.com/picupdate/" $filename = ((Get-Date -f s) -replace '[-T:]', '') $file = "$rootpath.png" -f $filename $PNGfile.Save($file) cd $rootpath $MARKDOWNpic=New-Object System.Collections.ArrayList $MARKDOWNpic.add('![image]('+$internetURL+$filename+'.png)') $MARKDOWNpic.Add(' ') $MARKDOWNpic|Set-Clipboard Write-Host "Pot-friends, now available in MarkDown Copy the text address in the editor" Import-Module D:\Posh-SSH\Posh-SSH.psd1 #Notice the module, I am not installing it here for use in the system $securestring=(Get-Content C:\picupdate\pass.txt).ToString() | ConvertTo-SecureString $ptr = [System.Runtime.InteropServices.Marshal]::SecureStringToGlobalAllocUnicode($secureString) $serverpass = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($ptr) $Password = ConvertTo-SecureString $serverpass -AsPlainText –Force $UserName = "kukisama" #Define Administrator Account Name $cred = New-Object System.Management.Automation.PSCredential($UserName,$Password) #upload Set-SCPFile -ComputerName "ny9s.com" -Port 62222 -Credential $cred -Remotepath "/var/www/html/picupdate" -LocalFile $($rootpath+$filename+'.png') $end=Get-Date echo $('Time consumed'+($end-$start).TotalSeconds) }Optimizable Items
Given how pictures take a few seconds to upload, it's logical to generate the strings MarkDown needs and upload them regularly, such as once in a minute or once in ten minutes.This will be a better experience.
Of course, after uploading, there should also be some flag bit detection, such as no upload after successful upload, record upload time, what it takes