我有一个网络摄像头,每两分钟将一个捕获的图像上传到一个网站,只需替换最后一个。我制作了一个Powershell脚本,每两分钟下载一次该图像,一切正常。但有时它会失去同步,因为从网络摄像头上传使用3G数据连接,我猜有时它会慢慢上传每个文件之间两分钟。 因此,当网络摄像头上传仍在进行时,我的脚本有时会下载一半图像。
在下载之前,有没有办法确保网络摄像头图像是完整上传的?
我试图让它在下载的图像中查找文件大小,如果它低于一定大小,它会立即被删除并保持我的downloadfolder从“垃圾”中清除,但由于图像有时大小不同而不是非常可靠的方法。
那么,如何在下载之前检查图像是否已完全上传?
这是我现在的代码
$imgNum = 0
while ($true)
{
cls
$storageDir = "C:\Temp\Norberg"
$url = "http://www.norberg.se/images/webcam/bild/image.jpg"
$file = "$storageDir\norberg_$(Get-Date -Format "yyyyMMdd-HHmmss").jpg"
Write-Host "---------------------------------------------------------------" -Fore "yellow"
Write-Host " Location: Norberg - Mimerlaven" -Fore "yellow"
Write-Host " Input: $url" -Fore "yellow"
Write-Host " Output: $file" -Fore "yellow"
Write-Host "---------------------------------------------------------------" -Fore "yellow"
$webclient = New-Object System.Net.WebClient
$webclient.DownloadFile($url,$file)
$numUp = ++$imgNum
$lastFile = gci $storageDir | sort LastWriteTime | select -last 1
$lastFileSize = $lastFile.Length
if ($lastFileSize -lt 100kb) {remove-item $storageDir"\"$lastFile}
Write-Host "Number of pictures taken: $imgNum" -Fore "yellow"
Write-Host "Last file size: "($lastFile.Length / 1KB) Kb -fore "yellow"
$x = 2*60
$length = $x / 100
while($x -gt 0) {
$min = [int](([string]($x/60)).split('.')[0])
$text = " " + $min + " minutes " + ($x % 60) + " seconds left"
Write-Progress "Tar nästa bild om..." -status $text -perc ($x/$length)
start-sleep -s 1
$x--
}
}
这个脚本的目的是我想要拍摄图像来制作一个游戏中时光倒流 - 视频,最初是24小时,但是将来我会想到每天拍摄一两张照片并制作一整年的游戏时光倒映来观看季节变化
答案 0 :(得分:0)
您可以添加以下代码来确定文件的大小,暂停然后再次检查大小并比较这两个值。重复,直到你得到两个文件大小相同的检查,表明它已经完成上传。
Function GetFileSize {
Param(
[parameter(Mandatory=$true)]
[System.Net.WebClient]
$Client,
[parameter(Mandatory=$true)]
[string]
$Url
)
$Client.OpenRead($url) | Out-Null
$Client.ResponseHeaders["Content-Length"]
}
do {
$filesize1 = GetFileSize -Client $webclient -Url $url
Start-Sleep -s 10
$filesize2 = GetFileSize -Client $webclient -Url $url
$difference = $filesize1 - $filesize2
}
until($difference -eq 0)
**代码未经测试**
答案 1 :(得分:0)
这是我的最终版本。将每个图像转换为HEX并查找.jpg文件的EndOfFile值。如果未找到EOF,请删除。
# Limit for how many days the images should be saved (Saving the last 7 days, deleting anything older).
$limit = (Get-Date).AddDays(-7)
# Reset the counter showing how many images have been downloaded since the script started
$imgNum = 0
# Reset the counter showing how many images have been deleted since the script started, older than $limit days
$DelImgNum = 0
# Where to save the imgages
$storageDir = "C:\Temp\webcam"
# Which image to download
$url = "http://www.norberg.se/webdav/files/Webbkamera/image.jpg"
# Two functions that read the downloaded image as HEX
function Join-String {
begin { $sb = New-Object System.Text.StringBuilder }
process { $sb.Append($_) | Out-Null }
end { $sb.ToString() }
}
function Format-HexString {
param([string[]]$path)
gc -en byte $path -Tail 10000 | % { '{0:X2}' -f $_ } | Join-String
}
$TestStorageDir = Test-Path $storageDir
if ($TestStorageDir -eq $False) {
Write-Host ""
Write-Host "[ERROR ] The folder you chose to use does not exist !!!" -fore "Red"
Write-Host ""
Return
}
# Starting the download
while ($true) {
cls
# Naming the downloaded files
$file = "$storageDir\norberg_$(Get-Date -Format "yyyyMMdd-HHmmss").jpg"
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host "---------------------------------------------------------------" -Fore "yellow"
Write-Host " Location: Norberg - Mimerlaven" -Fore "yellow"
Write-Host " URL: $url" -Fore "yellow"
Write-Host " Saved as: $file" -Fore "yellow"
Write-Host "---------------------------------------------------------------" -Fore "yellow"
$webclient = New-Object System.Net.WebClient
$webclient.DownloadFile($url,$file)
++$imgNum
$lastFile = gci $storageDir | sort LastWriteTime | select -last 1
$lastFileSize = $lastFile.Length
# Reading the last downloaded image as HEX
$imgEOF = Format-HexString $storageDir"\"$lastFile
# Trim all the zeros from the end of the file
$hex = $imgEOF.TrimEnd("0")
# Checking the last 4 bits of the file, looking for "FFD9" (EOF/End of File for .jpg file format). If FFD9 exist, save image, if not delete it.
# This is to make sure the image is totally upploaded from the webcam to the server where it´s beeing downloaded from.
# Earlier i experiensed problems where the scrip would download only a half image and it would be corrupt
# This makes sure the image is complete before saving it.
if ($lastFileSize -gt 0) {
$check = $hex.substring($hex.length - 4, 4)
if ($check -ne "FFD9")
{
#remove-item $storageDir"\"$lastFile
Write-Host "Number of pictures saved: $imgNum" -ForegroundColor Yellow
Write-Host "Number of pictures deleted: $DelImgNum" -ForegroundColor Yellow
Write-Host "Last 4 bits of image: $check" -ForegroundColor Yellow -NoNewline
Write-Host " DELETED (image was corrupt)" -ForegroundColor Red
++$DelImgNum
} else
{
Write-Host "Number of pictures saved: $imgNum"-ForegroundColor Yellow
Write-Host "Number of pictures deleted: $DelImgNum" -ForegroundColor Yellow
Write-Host "Last 4 bits of image: $check" -ForegroundColor Yellow
}
} else {
Write-Host " - Picture is 0kb, deleted it" -ForegroundColor Red
Remove-Item $storageDir"\"$lastFile
++$DelImgNum
}
# Deleting pictures older than x days, see variable $limit
Get-ChildItem -Path $storageDir -Recurse -Force | Where-Object { $_.CreationTime -lt $limit } | Remove-Item -Force
# Timer pausing the script before downloading the next picture, now set to 2x60 seconds = 2 minutes.
$x = 2*60
$length = $x / 100
while($x -gt 0) {
$min = [int](([string]($x/60)).split('.')[0])
$text = " " + $min + " minutes " + ($x % 60) + " seconds"
Write-Progress "Downloading next image in..." -status $text -perc ($x/$length)
start-sleep -s 1
$x--
}
}
答案 2 :(得分:-1)
WebClient client = new WebClient();
byte[] image_as_a_Byte = client.DownloadData("Your URL");
Image pic = (Bitmap)((new ImageConverter()).ConvertFrom(image_as_a_Byte));
pic.Save("yourImage.jpeg", ImageFormat.Jpeg);