您好,登錄后才能下訂單哦!
最近在學著用MarkDown寫文檔,對傳圖片深惡痛絕。準備自己用PowerShell造個輪子,還好提前搜索,找到了很多大哥的文檔。
整個要做的事情流程是
- 鼠標復制個剪貼板圖片
- 進入程序處理邏輯
- 處理剪貼板圖片,保存成本地文件(png或者jpg)
- 上傳到一個圖床,獲取圖床的連接
- 把圖床的鏈接構造成MarkDown要求的格式,塞回剪貼板。
- 回到MarkDown編輯器,直接剪貼。
目標是2階段的內容,完全用腳本實現。
PowerShell對文件的操作進行創建修改是比較簡單的,關鍵的地方在這里,用到了.net的方法直接去操作圖片
$img = [Windows.Clipboard]::GetImage()
根據這個關鍵字,我們看一下
Clipboard Class,里面有介紹到這個具體的方法
GetImage() | Returns a BitmapSource object from the Clipboard that contains data in the Bitmap format. |
---|
這里不光可以get,還可以set,不光是圖片,文字音頻都可以操作,算是針對剪貼板的一整套方案都有了。原文輸出的格式是PNG的,我想試試如何輸出JPG
剛才只是搞定了剪貼板的內容,接下來針對剪貼板數據,還需要保存成圖片。
這個可以學習下
ImageCodecInfo.GetImageEncoders Method
#剪貼板直接保存png
Add-Type -Assembly PresentationCore
$img = [Windows.Clipboard]::GetImage()
if ($null -eq $img ) {
Write-Host "剪貼板無圖"
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/{0}.jpg" -f $filename
Write-Host ("`n 找到圖片. {0}x{1} 像素,保存到{2}`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()
{
Bitmap bmp1 = new Bitmap(typeof(Button), "Button.bmp");
bmp1.Save(@"c:\button.png", ImageFormat.Png);
}
#相對簡單存儲圖片
#https://stackoverflow.com/questions/41665/bmp-to-jpg-png-in-c-sharp
#高級存儲圖片
#https://stackoverflow.com/questions/1484759/quality-of-a-saved-jpg-in-c-sharp
#官方例子
#https://docs.microsoft.com/en-us/dotnet/api/system.drawing.imaging.imagecodecinfo.getimageencoders?view=netframework-4.8
這里用到了一個技巧,就是 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)
# 創建新圖像
$NewImage = [System.Drawing.Bitmap]::new($Image.Width,$Image.Height)
$NewImage.SetResolution($Image.HorizontalResolution,$Image.VerticalResolution)
#根據新圖像添加圖形
$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
#存儲
$NewImage.Save("c:\img\vvv.jpg",$imageFormat::Jpeg)
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()
github是個不要錢的圖床,它支持用git來上傳下載文件。
git config --global user.name "用戶名"
git config --global user.email "用戶郵箱"
cd ~/.ssh
ssh-keygen -t rsa -C "用戶郵箱"
#上面這一步是生成一個證書,用來和github通信。
打開這里,在右側菜單欄中找到SSH and GPG keys
,選擇new SSH key
,輸入title,下面key的內容就是本機ssh key
,也就是剛才生成的公鑰,直接將id_rsa.pub中的內容粘貼過來就可以,然后點擊下面的add SSH key即可完成。
輸入這個命令cat id_rsa.pub
,會出來類似下面的東西,復制出來,這就是密鑰ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDRyubAWD7PfF+baIYAYVpdtTag7YZYdmCNz2mkoMjxkP6aN5C/Rnxxxxxxxxxxxxxxxxxxxxx5sSNV42co5S4Tc5W3eBB9bPBIoObqZ/g8JkCVrEIgUXTO1rn9p7h6erQ0/TcC/tIQ+HVxVx+mV7Y/wcYY05+Bbm8Cv60= a9y@live.cn
git remote add origin https://github.com/kukisama/kukisama.github.io
加個本地目錄
git add c:/gitupdate/picupdate/tt.txt
上傳本地文件
git commit -m "來個描述"
git push origin master
拉回來
git pull origin master
上傳
前置條件準備的差不多了,可以看看完整代碼。
#剪貼板直接保存png
Add-Type -Assembly PresentationCore
$img = [Windows.Clipboard]::GetImage()
if ($null -eq $img ) {
Write-Host "剪貼板無圖"
}
$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{0}.png" -f $filename
Write-Host ("`n 找到圖片. {0}x{1} 像素,保存到{2}`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 "盆友,現在可以在MarkDown編輯器里面復制文本地址了"
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/
功能邏輯基本算是完工了,但是突然我搜到這么一篇神帖
看帖子的時間,2015年就已經有這邏輯了……………………
這里有一個原生命令,Set-Clipboard
以及Get-Clipboard
所以保存文件只需要兩步
$PNGfile=Get-Clipboard -Format Image
$PNGfile.Save($file)
所以修改后的邏輯是這樣的
$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{0}.png" -f $filename
$PNGfile.Save($file)
cd $rootpath;cd ..
$MARKDOWNpic=New-Object System.Collections.ArrayList
#$MARKDOWNpic.add('![image]('+$interneturl+$filename+'.png'+')')
#上面這個地址是github page的地址,但是實際來看,這個地址刷新的速度很慢,所以我直接取了文件的時間地址
$MARKDOWNpic.add('![image]('+'https://github.com/kukisama/kukisama.github.io/blob/master/picupdate/'+$filename+'.png'+'?raw=true)')
$MARKDOWNpic.Add(' ')
$MARKDOWNpic|Set-Clipboard
Write-Host "盆友,現在可以在MarkDown編輯器里面復制文本地址了"
git add $file
git commit -m $filename
git push
}
還收獲了一個小技巧:針對對象輸出的屏幕字符,可以先轉換成字符串,然后輸出到剪貼板
dir | Out-String | Set-Clipboard
github page的圖床真的是不能明著說,反正國內就是不穩定。這里初步想法是使用最妥的FTP來完成圖片的保存工作,自己架設一個FTP服務器,假設名字是 xxx.ny9s.com
實際對應web站點 ny9s.com/pic 實際要做的就是把圖片傳到FTP,然后生成對應的web端的字符串。 再次修改下腳本。
先照著Ubuntu16.04安裝ftp服務器去配置一下
sudo apt-get install vsftpd
創建用戶目錄 sudo mkdir picupdate
創建用戶 sudo useradd -d /var/www/html/picupdate -s /bin/bash uftp
sudo mkdir picupdate
sudo vi /etc/vsftpd.conf
#編輯vsftpd.conf文件
userlist_deny=NO
userlist_enable=YES
#允許登錄的用戶
userlist_file=/etc/allowed_users
seccomp_sandbox=NO
#默認ftp下載目錄
local_root=/home/uftp/
local_enable=YES
#設置文件上傳
write_enable=YES
#使用utf8
utf8_filesystem=YES
添加允許登錄的用戶
sudo gedit /etc/allowed_users
修改完之后保存,然后可以重啟服務
sudo /etc/init.d/vsftpd start
sudo /etc/init.d/vsftpd stop
sudo /etc/init.d/vsftpd restart
如果是開被動模式的花,
打開xxx/vsftpd/vsftpd.conf,在末尾添加:
pasv_enable=YES //開啟PASV模式
pasv_min_port=40000 //最小端口號
pasv_max_port=40000 //最大端口號
pasv_promiscuous=YES
再配置下權限
sudo chown uftp:uftp /var/www/html/picupdate/
# 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
vsftpd啟動后,默認的ftp端口是21,現在我想把ftp端口改成 801 ,修改后能保證用戶上傳下載不受影響
1.編輯 /etc/vsftpd/vsftpd.conf 文件,在該配置文件中添加此行:listen_port=801
2.編輯 /etc/services 文件,將其中的
ftp 21/tcp 改為 ftp 801/tcp
ftp 21/udp改為 ftp 801/udp
3.執行 /etc/init.d/vsftpd restart 重新啟動 vsftpd 服務。啟動完成后可以使用 netstat -ntpl | grep vsftpd 命令可以查看到系統現
監聽的 vsftpd 的端口為 801
4.使用 lftp 192.168.0.1:801(192.168.0.1 是 vsftpd 服務器的地址 ),這樣就可以訪問到 ftp 服務器了。
開啟防火墻
ufw enable
關閉防火墻
ufw disable
然而上面的問題雖然看起來步驟應該很詳細了,但是問題是在我的環境配置失敗了……
花了很多時間在FTP上,開始繼續尋找解決方案。經過測試,最簡單的方法是安裝Posh-SSH模塊,用SSH的方式去上傳下載文件。這個模塊在github可以下載到。
另外也可以使用Install-Module -Name Posh-SSH -RequiredVersion 2.0.2
直接安裝,我覺得優點如下:
$cred=Get-Credential
#同意KEY,從遠程下載文件
Get-SCPFile -ComputerName "ny9s.com" -Port 12121 -Credential $cred -RemoteFile "/home/kukisama/IOid.jpg" -LocalFile 'C:\img\ppp.jpg' -AcceptKey
#上傳
Set-SCPFile -ComputerName "ny9s.com" -Port 12121 -Credential $cred -Remotepath "/home/kukisama" -LocalFile 'C:\img\ppp.jpg'
如果是在線安裝的話,模塊會位于C:\Program Files\WindowsPowerShell\Modules\Posh-SSH
如果不要了,直接刪除就相當于卸載。
整體目錄有2.26MB,有500K的幫助文件,測試后,發現刪除沒影響(en-US目錄)。
為了靜默連接SSH,所以用到一個密碼邏輯,它可將所需要用到的$cred加密放在本地文件夾中,使用的時候會比較簡單
#步驟1、將密碼加密后保持到c:\xxx.txt。
$mysecret="xxxxxx" #此處放密碼
$mysecret|ConvertTo-SecureString -AsPlainText -Force |ConvertFrom-SecureString|Out-File C:\picupdate\pass.txt -Encoding utf8
#步驟2、將密文密碼轉換成powershell可以使用的格式
$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
#步驟3、使用
$UserName = "admin" #定義管理員賬戶名稱
$cred = New-Object System.Management.Automation.PSCredential($UserName,$Password)
$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{0}.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 "盆友,現在可以在MarkDown編輯器里面復制文本地址了"
Import-Module D:\Posh-SSH\Posh-SSH.psd1 #注意模塊,我這里是沒有安裝到系統中使用的
$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" #定義管理員賬戶名稱
$cred = New-Object System.Management.Automation.PSCredential($UserName,$Password)
#上傳
Set-SCPFile -ComputerName "ny9s.com" -Port 62222 -Credential $cred -Remotepath "/var/www/html/picupdate" -LocalFile $($rootpath+$filename+'.png')
$end=Get-Date
echo $('消耗時間'+($end-$start).TotalSeconds)
}
考慮到圖片上傳怎么樣都需要個幾秒鐘,所以邏輯上可以先生成MarkDown所需要的字符串,然后定期去上傳,比如一分鐘或者十分鐘一次。這樣體驗上會好一些。
當然,上傳完畢也要做一些標志位的檢測,比如上傳成功后,再也不會上傳,記錄上傳時間,消耗時間什么的
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。