编写脚本以复制特定尺寸的图像

时间:2019-06-13 02:33:37

标签: powershell scripting

我想做的是让脚本遍历照片目录(即C:\ user \ userid \ Pictures),包括子目录,然后复制大于LxH尺寸(即1920x1080)的目录到另一个文件夹(即C:\ user \ userid \ Destination)。该程序将在Windows机器上运行,该机器的主文件夹中包含超过一百万张照片和300多个子目录。速度对我来说不是问题(任何事情都比手动遍历每个子目录要快),因此即使是需要花费几天时间才能完成的事情,也绰绰有余。

所以算法可能看起来像这样:

string streetName = "patrick portland vic";

string[] split = streetName.Split(' ');
string[] chars = { "*", "~" };

IEnumerable<IEnumerable<string>> choices = split.Select(n => chars.Select(c => $"{n}{c}"));

IEnumerable<IEnumerable<string>> result = choices.CartesianProduct();

但是我可能会完全失去使用脚本语言的意义。

我已经看到Powershell有一个Function findLargeImages(curr, dest): For each file/folder in curr: if file: if file is image: if (image.width >= ####) AND (image.height >= ####) copy image to dest else if folder: findImage(folder, dest) return (the sound of happiness) Copy-Item,但是我不知道如何使用它们,因为我对Powershell的了解是它是蓝色的,并在命令行上“替换”了。我既缺乏安全遍历文件系统的知识,又缺乏获得某种属性来确定图像高度/宽度的知识。

Powershell是我开始研究此功能时遇到的第一件事,但是如果它可以在Windows上运行,那么我会感到非常高兴。我可以轻松安装大多数其他语言,并在需要时运行该代码。如果已经有一些软件可以执行此操作,那么您的Google-fu远比我的强大。

万一我丢失了登录信息,非常感谢任何提前提供帮助的人!

2 个答案:

答案 0 :(得分:1)

您可以使用.NET System.Drawing.Image类进行此操作:

$source      = 'C:\user\userid\Pictures'
$destination = 'C:\user\userid\Destination'
$maxWidth    = 1920
$maxHeight   = 1080

# if the destination path does not exist, create it
if (!(Test-Path -Path $destination -PathType Container)) {
    New-Item -Path $destination -ItemType Directory | Out-Null
}

# Add System.Drawing assembly
Add-Type -AssemblyName System.Drawing

Get-ChildItem -Path $source -File -Recurse | ForEach-Object {
    # capture the full filename so we can use it in the catch block
    $fileName = $_.FullName
    # Open image file
    try {
        $img = [System.Drawing.Image]::FromFile($fileName)
        # use '-ge'  if you want to copy files with a width and/or height Greater Or Equal To the max dimensions
        # use '-and' if you want to copy files where both the Width and the Height exceed the max dimensions
        if ($img.Width -gt $maxWidth -or $img.Height -gt $maxHeight) {
            $_ | Copy-Item -Destination $destination -Force
        }
    }
    catch {
        Write-Warning "Could not open file '$fileName'. Not an image file?"
    }
}

答案 1 :(得分:0)

至少您的示例中有逻辑。我怀疑大多数人会为您敲门。

我假设您不知道如何编写代码以达到此任务所需的级别,请花一点时间来学习和理解以下解决方案。如有需要,问问题。

# Parent Directory
$Directory = "C:\user\userid\" 

# This includes any folders with the word Pictures in the file path
$Folders = Get-ChildItem -Dir $Directory -Recurse -Include "*Pictures*"
$objShell = New-Object -ComObject Shell.Application

Foreach($Folder in $Folders) {
    $objFolder = $objShell.namespace($Folder.FullName)
    Foreach ($file in $objFolder.Items()){

        # Index 31 is the Dimensions in the metadata
        # Splits it as it returns 3880 x 5184 as an example
        $Dimensions = $objFolder.getDetailsOf($File, 31) -split ' x '
        # Index 165 is the Extension in the metadata, e.g. ".JPG"
        $FileType = $objFolder.getDetailsOf($File, 165)

        # If 3880 is greater than or equal to 1920 AND 5184 is greater than or equal to 1080
        If(($Dimensions[0] -ge 1920) -and ($Dimensions[1] -ge 1080) -and ($FileType -in ('.jpg','.png'))) {
            Copy-Item -Path $File.Path -Destination 'C:\user\userid\Destination' 
        }
    } 
}