Sips.PowerCli.psm1

#Requires -Version 7

$AcceptExtensions = @(".jpg", ".jpeg", ".heic", ".png")

function ConvertTo-SipsJpgExif(
    [int] $Quality = 30,
    [string] $InputDir
) {
    if (!$InputDir) {
        $InputDir = $(Get-Location).Path
    }

    $outputDir = Join-Path -Path $inputDir -ChildPath "/processed"

    $images = Get-ChildItem -Path $inputDir
                | ? { $_.extension -in $AcceptExtensions }

    Test-Images -Images $images
    Test-OutDir -OutputDir $outputDir

    $processedImages = $images
        | Convert-Image -Quality $Quality -OutputDir $outputDir
        | ForEach-Object {
            $inSize = $_.From.Length.ToString("N0")
            $outSize = $_.To.Length.ToString("N0")
            $diffPercent = ($outSize / $inSize).ToString("P")
            Write-Host "$(Split-Path $_.From -Leaf) → $($_.To) ($inSize b → $outSize b) ($diffPercent)"
            $_
        }

    $originalSizeSum = ($images | Measure-Object -Property Length -sum).Sum
    $outSizeSum = ($processedImages
        | ForEach-Object { Get-Item $_.To }
        | Measure-Object -Property Length -sum).Sum
    $diffPercent = ($outSizeSum / $originalSizeSum).ToString("P")

    Write-Host "$($originalSizeSum.ToString('N0')) b → $($outSizeSum.ToString('N0')) b"
    Write-Host "→ $diffPercent"
}

function Convert-Image(
    [int] $Quality,
    $OutputDir
) {
    process {

        $inFile = $_
        $outFileName = Join-Path -Path $OutputDir -ChildPath "$($inFile.BaseName).jpg"

        sips -s format jpeg -s formatOptions $Quality $inFile.FullName --out $outFileName > $null

        $outFile = Get-Item $outFileName

        return [PSCustomObject]@{
            From = $inFile;
            To   = $outFile
        }
    }
}

function Test-Images(
    $Images
) {
    if ($Images.Count -eq 0) {
        Write-Host "no images are found or accessible"
        break
    }
}

function Test-OutDir(
    $OutputDir
) {
    if (!(Test-Path -Path $OutputDir)) {
        New-Item -Path $OutputDir -ItemType "directory" > $null
    }
    else {
        $existingFiles = Get-ChildItem -Path $OutputDir
        if ($existingFiles.Count -gt 0) {
            Write-Host "output folder is not empty"
            break
        }
    }
}