1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Windows】スクショのpngを自動圧縮する(但し対象はpngのみ)

1
Posted at

きっかけ

以前、Mac miniで動かしていた「Desktopに置いたpngを自動で圧縮する」仕組みを、Windows側でも欲しくなりました。fswatch、launchd、osascriptはいずれもmacOS専用なので、Windowsでは素直に別物へ置き換える必要があります。

やりたいことは同じで、キャプチャフォルダを監視して、pngが増えたらpngquantとoxipngで圧縮し、通知だけ出してログファイルは一切残しません。この記事ではその実装を、実際にハマった箇所も含めてまとめます。

この記事でできるようになること

任意のフォルダ(今回はスクリーンショット保存先のCaptures)を監視して自動でpngを圧縮し、サインイン時に自動でバックグラウンド起動するようになります。圧縮完了時にはWindowsのトースト通知で削減率が分かり、ログファイルは一切残らない構成になります。

準備

パッケージマネージャはScoopを使います。管理者権限は不要で、非管理者権限での利用を前提に設計されているツールなので、通常のPowerShellで進めます。
※既にインストールされていれば不要です

Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
irm get.scoop.sh | iex

scoopでインストール

scoop install pngquant oxipng

通知用にBurntToastも入れます。

Install-Module -Name BurntToast -Scope CurrentUser -Force

Set-ExecutionPolicy実行時に「アクセスが拒否されました」が出る場合は、管理者権限のPowerShellを開いていないか確認する。ScoopはあえてPATHの通し方を非管理者権限前提で設計しているため、管理者権限だと逆に警告が出て失敗することがあるようです。

監視スクリプト

C:\Users\<ユーザー名>\Scripts\png-compress-watch.ps1として保存します。

$global:WatchDir  = "<スクショが保存されるフォルダ>"
$global:OutputDir = "$global:WatchDir\compressed"

New-Item -ItemType Directory -Force -Path $global:OutputDir | Out-Null

$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = $global:WatchDir
$watcher.Filter = "*.png"
$watcher.IncludeSubdirectories = $false
$watcher.EnableRaisingEvents = $true

$action = {
    $path = $Event.SourceEventArgs.FullPath

    if ($path -like "*\compressed\*") { return }
    if (-not (Test-Path $path)) { return }

    $lastSize = -1
    while ($true) {
        if (-not (Test-Path $path)) { return }
        $currentSize = (Get-Item $path).Length
        if ($currentSize -eq $lastSize -and $currentSize -gt 0) { break }
        $lastSize = $currentSize
        Start-Sleep -Milliseconds 300
    }

    $filename   = Split-Path $path -Leaf
    $outputPath = Join-Path $global:OutputDir $filename
    $beforeSize = (Get-Item $path).Length

    & pngquant --quality=65-85 --output $outputPath --force $path 2>$null
    if ($LASTEXITCODE -ne 0) {
        Copy-Item $path $outputPath -Force
    }

    & oxipng -o 4 -q $outputPath 2>$null

    $afterSize = (Get-Item $outputPath).Length
    $reduced = [math]::Round(100 - ($afterSize * 100 / $beforeSize), 1)

    $msg = "$filename : ${beforeSize}B to ${afterSize}B (${reduced} percent reduced)"
    New-BurntToastNotification -Text "PNG Compress Done", $msg
}

Register-ObjectEvent -InputObject $watcher -EventName "Created" -Action $action | Out-Null
Register-ObjectEvent -InputObject $watcher -EventName "Renamed" -Action $action | Out-Null

Write-Host "Watching: $global:WatchDir"
while ($true) { Start-Sleep -Seconds 1 }

監視先はスクリーンショットやゲームバーの録画が保存されるフォルダにしました。Win+Alt+PrtScnで撮ったキャプチャがそのまま自動圧縮されます。

Renamedイベントも監視しているのには理由があります。Windowsの一部のキャプチャツールは、書き込み中は一時ファイル名で保存し、完了後に本来のファイル名へリネームします。Createdイベントだけだとこの変化を取りこぼすことがあるため、Renamedも合わせて監視対象にしています。

タスクスケジューラで常駐化

サインイン時の自動起動はタスクスケジューラに任せます。

$action = New-ScheduledTaskAction -Execute "powershell.exe" `
  -Argument "-WindowStyle Hidden -ExecutionPolicy Bypass -File `"$env:USERPROFILE\Scripts\png-compress-watch.ps1`""

$trigger = New-ScheduledTaskTrigger -AtLogOn

$principal = New-ScheduledTaskPrincipal -UserId "$env:USERDOMAIN\$env:USERNAME" -LogonType Interactive

$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -ExecutionTimeLimit ([TimeSpan]::Zero)

Register-ScheduledTask -TaskName "PngCompressWatch" -Action $action -Trigger $trigger -Principal $principal -Settings $settings

アクセス拒否のエラーが発生した場合はPowerShellを管理者権限で実行してみます。

タスクの起動・停止・削除は以下の通りです。

Stop-ScheduledTask -TaskName "PngCompressWatch"
Start-ScheduledTask -TaskName "PngCompressWatch"
Unregister-ScheduledTask -TaskName "PngCompressWatch" -Confirm:$false

動作確認

新しいPowerShellウィンドウを開いて(Scoopインストール直後はPATH反映のため必須です)手動実行します。

& "$env:USERPROFILE\Scripts\png-compress-watch.ps1"

Watching: <フォルダ名>と表示されたら、Win+Alt+PrtScnでキャプチャを撮ってみます。compressedフォルダに圧縮版が生成され、トースト通知が出れば成功です。問題なければCtrl+Cで止めて、タスクスケジューラ経由の常駐に任せます。

キャプチャして、

AI 3Dモデル ジェネレーター:テキスト&画像から3Dを作成 _ Meshy - Google Chrome 2026_07_15 10_50_31.png

AI 3Dモデル ジェネレーター:テキスト&画像から3Dを作成 _ Meshy - Google Chrome 2026_07_15 10_50_31.pngのプロパティ 2026_07_15 10_51_09.png

↓compressedに圧縮された画像が保存されます

AI 3Dモデル ジェネレーター:テキスト&画像から3Dを作成 _ Meshy - Google Chrome 2026_07_15 10_50_31.png

AI 3Dモデル ジェネレーター:テキスト&画像から3Dを作成 _ Meshy - Google Chrome 2026_07_15 10_50_31.pngのプロパティ 2026_07_15 10_51_23.png

まとめ

  • fswatch pngquant oxipngをインストール(無ければscoopも)
  • 監視スクリプトを作成
  • タスクスケジューラで常駐化
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?