Написание скрипта для копирования изображений определенных размеров - PullRequest
0 голосов
/ 13 июня 2019

То, что я хочу сделать, - это запустить скрипт через каталог фотографий (например, C: \ user \ userid \ Pictures), включая подкаталоги, и скопировать те, которые больше размера LxH (например, 1920x1080)в другую папку (например, C: \ user \ userid \ Destination).Это будет выполняться на машине с Windows, содержащей более миллиона фотографий и более 300 подкаталогов в своей основной папке.Скорость не является для меня проблемой (что-то быстрее, чем проходить через каждый подкаталог вручную), поэтому даже того, что требует буквальных дней, этого более чем достаточно.

Так что алгоритм может выглядеть как-токак это:

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)

Но я мог бы полностью упустить смысл использования языка сценариев.

Я видел, что у Powershell есть Copy-Item и Get-ChildItem, но яЯ не знаю, как их использовать, так как я знаю Powershell, что он синий и «заменил» командную строку.Мне не хватает знаний для безопасного обхода файловой системы и получения какого-то свойства для определения высоты / ширины изображения.

Powershell - это первое, с чем я столкнулся, когда начал изучать это, но если этоможно запустить на винде, тогда я буду более чем счастлив.Я мог бы легко установить большинство других языков и запустить этот код при необходимости.Если для этого уже есть какое-то программное обеспечение, то ваш Google-фу намного больше моего.

В случае, если мне удастся потерять информацию для входа в систему, ОГРОМНОЕ спасибо всем, кто заранее поможет!

Ответы [ 2 ]

1 голос
/ 13 июня 2019

Вы можете сделать это, используя .NET System.Drawing.Image class:

$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?"
    }
}
0 голосов
/ 13 июня 2019

По крайней мере, у вас есть логика в вашем примере.Я сомневаюсь, что большинство людей подберут что-нибудь для вас.

Я предполагаю, что вы не знаете, как написать код на уровне, необходимом для этой задачи. Пожалуйста, уделите немного времени, чтобы изучить и понять приведенное ниже решение.Задайте вопросы, если это необходимо.

# 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' 
        }
    } 
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...