Как изменить размер нескольких изображений сразу через PowerShell
Обработка фотографий по одной быстро превращается в утомительную рутину, особенно когда в папке находятся десятки или сотни файлов. Графические редакторы справляются с такой задачей, но часто требуют ручной настройки пакетной обработки, установки дополнительных модулей или запуска тяжёлого интерфейса.
PowerShell позволяет автоматизировать уменьшение изображений прямо в Windows. Сценарий может пройти по всем JPG и PNG в выбранной папке, рассчитать новые размеры с сохранением пропорций и положить готовые файлы в отдельный каталог.
Такой подход полезен при подготовке иллюстраций для сайта, резервных копий фотографий и материалов, которые нужно быстро загрузить в WordPress. Например, перед публикацией подборки изображений, посвящённой подготовке фото к публикации, можно уменьшить исходники без изменения каждого файла вручную.
Ниже используется стандартная библиотека .NET System.Drawing, поэтому отдельная программа для базового изменения размера не понадобится. Перед массовой обработкой всё же стоит сделать копию исходной папки: это позволит спокойно проверить результат и при необходимости изменить параметры.
Подготовка папки и инструментов
Создайте рядом со скриптом две папки: originals для исходных изображений и resized для готовых файлов. В первую переместите фотографии, которые требуется обработать. Раздельное хранение важно: сценарий не будет перезаписывать оригиналы, а результат можно будет удалить или пересоздать без риска потери данных.
В примере обрабатываются файлы с расширениями .jpg, .jpeg и .png. Изображения GIF, TIFF или WebP в этот список не входят, поскольку у них есть особенности анимации, прозрачности и поддержки кодека. При необходимости расширения можно добавить после проверки совместимости.
Для запуска подойдёт Windows PowerShell 5.1. В PowerShell 7 библиотека System.Drawing также может работать в Windows, но на Linux и macOS этот вариант менее удобен. Для кроссплатформенной обработки лучше применять ImageMagick или отдельный модуль, а приведённый способ оставить для компьютеров с Windows.
Как работает сценарий
Сначала скрипт получает список файлов, затем открывает каждое изображение и сравнивает его ширину с заданным ограничением. Если исходник уже меньше максимальной ширины, его можно оставить без увеличения. Это защищает маленькие картинки от искусственного растягивания и потери резкости.
Новая высота вычисляется по формуле сохранения пропорций: исходная высота умножается на новую ширину и делится на исходную ширину. После этого создаётся новый объект Bitmap, а изображение перерисовывается в него с качественным режимом интерполяции. Оригинальный файл при этом не изменяется.
Для JPEG задаётся качество 85 процентов. Это разумный компромисс для веб-страниц: размер файла обычно заметно уменьшается, а визуальные потери остаются малозаметными. PNG сохраняется без преобразования в JPEG, поэтому прозрачность и особенности формата сохраняются.
Пакетное уменьшение JPEG и PNG
Сохраните следующий код в файл resize-images.ps1. Значение $maxWidth задаёт максимальную ширину готового изображения в пикселях. Например, 1600 подходит для большинства публикаций, а для миниатюр можно использовать 800 или 1200.
$source = Join-Path $PWD "originals"
$target = Join-Path $PWD "resized"
$maxWidth = 1600
$quality = 85
New-Item -ItemType Directory -Path $target -Force | Out-Null
Add-Type -AssemblyName System.Drawing
$files = Get-ChildItem -Path $source -File |
Where-Object { $_.Extension -match '\.(jpg|jpeg|png)$' }
$jpegCodec = [System.Drawing.Imaging.ImageCodecInfo]::GetImageEncoders() |
Where-Object { $_.MimeType -eq 'image/jpeg' }
foreach ($file in $files) {
$image = [System.Drawing.Image]::FromFile($file.FullName)
try {
if ($image.Width -gt $maxWidth) {
$newWidth = $maxWidth
$newHeight = [int]($image.Height * $newWidth / $image.Width)
}
else {
$newWidth = $image.Width
$newHeight = $image.Height
}
$bitmap = New-Object System.Drawing.Bitmap($newWidth, $newHeight)
try {
$graphics = [System.Drawing.Graphics]::FromImage($bitmap)
try {
$graphics.InterpolationMode =
[System.Drawing.Drawing2D.InterpolationMode]::HighQualityBicubic
$graphics.SmoothingMode =
[System.Drawing.Drawing2D.SmoothingMode]::HighQuality
$graphics.DrawImage($image, 0, 0, $newWidth, $newHeight)
}
finally {
$graphics.Dispose()
}
$destination = Join-Path $target $file.Name
if ($file.Extension -match '\.(jpg|jpeg)$') {
$encoderParameters = New-Object System.Drawing.Imaging.EncoderParameters(1)
$encoderParameters.Param[0] = New-Object System.Drawing.Imaging.EncoderParameter(
[System.Drawing.Imaging.Encoder]::Quality, [long]$quality
)
$bitmap.Save($destination, $jpegCodec, $encoderParameters)
$encoderParameters.Dispose()
}
else {
$bitmap.Save($destination, [System.Drawing.Imaging.ImageFormat]::Png)
}
}
finally {
$bitmap.Dispose()
}
}
finally {
$image.Dispose()
}
Write-Host "Готово: $($file.Name)"
}
Папка resized создаётся автоматически, поэтому заранее создавать её необязательно. Имена файлов сохраняются, а расширение остаётся прежним. Если в каталоге назначения уже есть файл с таким именем, PowerShell перезапишет его, поэтому перед повторным запуском проверьте, не нужны ли старые результаты.
Сохранение пропорций и качества
Основная настройка сценария — $maxWidth. Она ограничивает ширину, но не заставляет все картинки иметь одинаковый размер. Фотография 4000×3000 станет 1600×1200, а вертикальный снимок 3000×4000 превратится в 1200×1600. Такое поведение сохраняет исходное соотношение сторон.
Параметр $quality применяется только к JPEG. Значение 85 подходит для фотографий, скриншотов с большим количеством цветов и большинства иллюстраций. Если важна экономия места, можно попробовать 75–80. Для архивного хранения лучше использовать более высокое качество или не заменять исходные изображения сжатой копией.
PNG не следует бездумно переводить в JPEG. У PNG хорошо сохраняются прозрачный фон, резкие границы и небольшие схемы. Если картинка содержит текст, логотип или интерфейсный скриншот, PNG часто выглядит лучше даже при большем размере файла. Для веб-страниц, где важна скорость, дополнительную оптимизацию можно выполнять отдельными инструментами.
Запуск в Windows PowerShell
Откройте папку со скриптом, щёлкните по адресной строке Проводника, введите powershell и нажмите Enter. В появившемся окне выполните:
Set-ExecutionPolicy -Scope Process Bypass
.\resize-images.ps1
Параметр -Scope Process временно разрешает запуск сценариев только в текущем окне и не меняет глобальную политику безопасности Windows. Если файл был загружен из интернета, система может пометить его как полученный из внешнего источника. В таком случае можно выполнить:
Unblock-File .\resize-images.ps1
После запуска в консоли появится сообщение для каждого обработанного файла. Если необходимо запускать сценарий из другой папки, замените $PWD на полный путь, например C:\Users\User\Pictures\Batch. Это особенно удобно при регулярной подготовке изображений для сайта. Перед публикацией также полезно проверить ускорение загрузки WordPress, поскольку одних уменьшенных картинок иногда недостаточно.
Обработка ошибок и безопасная проверка
Самая частая проблема возникает, когда файл повреждён, имеет неправильное расширение или занят другой программой. В таком случае Image.FromFile() выдаст ошибку, и обычный цикл может остановиться. Для большого набора файлов удобно добавить обработчик try/catch, чтобы пропустить проблемный элемент и продолжить работу.
Например, тело обработки можно дополнить таким фрагментом:
try {
$image = [System.Drawing.Image]::FromFile($file.FullName)
# Остальная обработка файла
}
catch {
Write-Warning "Не удалось обработать $($file.Name): $($_.Exception.Message)"
continue
}
Перед массовым запуском протестируйте сценарий на трёх или пяти изображениях разных типов: горизонтальном, вертикальном, маленьком и с прозрачностью. Сравните размеры исходников и результатов, откройте PNG на фоне другого цвета, проверьте читаемость мелкого текста. Такая проверка помогает заметить нежелательное преобразование ещё до обработки всей коллекции.
Некоторые фотографии могут содержать EXIF-данные, включая ориентацию, модель камеры и координаты. System.Drawing не предназначен для полноценного управления метаданными, поэтому после обработки стоит проверить, какая информация сохранилась. Если конфиденциальность важна, удаляйте GPS-данные отдельной программой перед публикацией.
Практика для сайта и повторное использование
Для изображений в статьях обычно достаточно ширины от 1200 до 1600 пикселей. Более крупные файлы редко улучшают отображение на обычном экране, зато увеличивают время загрузки и расход дискового пространства. Для баннеров и карточек можно создать отдельный вариант сценария с меньшим лимитом, чтобы не использовать полноразмерные фотографии там, где они не нужны.
Если на сайте размещаются материалы с описанием цифровых сервисов или промо-страниц, изображения лучше готовить одинаково: применять понятную схему имён, хранить исходники отдельно и не загружать случайные гигантские файлы. Например, для страницы с описанием бонуса за регистрацию достаточно заранее подготовить компактные иллюстрации, которые быстро открываются на мобильном интернете.
Сценарий легко приспособить под другие задачи. Можно добавить суффикс _small к имени результата, создать отдельные папки для форматов, ограничить обработку только файлами новее определённой даты или включить автоматический запуск через Планировщик заданий Windows. Главное — сохранять оригиналы и явно разделять этапы подготовки.
PowerShell подходит для регулярного изменения размера изображений, когда требуется простая, прозрачная и повторяемая процедура. Скопируйте код в файл, проверьте его на небольшой подборке и настройте ширину под конкретный тип публикаций. После этого пакетная обработка фотографий займёт несколько секунд вместо ручного редактирования каждого файла.