PSImageConverter

0.2.0-preview0013

Cross-platform PowerShell 7 module for converting images such as HEIC/HEIF photos to JPEG, PNG, WebP, AVIF and more, powered by Magick.NET. Pipeline-friendly; keeps the EXIF metadata in JPEG, PNG, WebP, AVIF and JPEG XL output.

Minimum PowerShell version

7.4

This is a prerelease version of PSImageConverter.

Installation Options

Copy and Paste the following command to install this package using PowerShellGet More Info

Install-Module -Name PSImageConverter -AllowPrerelease

Copy and Paste the following command to install this package using Microsoft.PowerShell.PSResourceGet More Info

Install-PSResource -Name PSImageConverter -Prerelease

You can deploy this package directly to Azure Automation. Note that deploying packages with dependencies will deploy all the dependencies to Azure Automation. Learn More

Manually download the .nupkg file to your system's default download location. Note that the file won't be unpacked, and won't include any dependencies. Learn More

Owners

Copyright

(c) Ing. Fabian Steiner BSc. All rights reserved.

Package Details

Author(s)

  • Ing. Fabian Steiner BSc.

Tags

HEIC HEIF Image Conversion JPEG PNG WebP AVIF JpegXL ImageMagick MagickNET Windows Linux MacOS

Functions

Convert-Image ConvertFrom-Heic ConvertTo-Avif ConvertTo-Jpeg ConvertTo-JpegXL ConvertTo-Png ConvertTo-WebP Get-ImageInfo

PSEditions

Core

Dependencies

This module has no dependencies.

Release Notes

## [0.2.0-preview0013] - 2026-10-18

### Added

- `Convert-Image`: Converts every image Magick.NET can read (HEIC/HEIF, JPEG, PNG, WebP, AVIF, TIFF, ...) to Jpeg, Png, WebP, Avif, Jxl (JPEG XL), Tiff, Bmp or Gif. `-Path` with wildcards, `-LiteralPath` (pipeline input from `Get-ChildItem` and `Get-ImageInfo`, folders are skipped, a file given twice is converted once), `-DestinationPath`, `-Quality` (lossy formats Jpeg, WebP, Avif, Jxl), `-Force`, `-WhatIf` and `-Confirm`. Applies the EXIF orientation (and then removes the EXIF thumbnail and updates the XMP orientation and pixel dimensions) and keeps the metadata the output format can carry unless `-StripMetadata` is used, which removes EXIF (including GPS), XMP, IPTC and comments but keeps the ICC colour profile (in PNG output only as iCCP chunk; PNG, JPEG and TIFF output of neutral grey pixels with an RGB profile is stored as RGB, so readers accept the profile). Warns when Tiff, Gif or Bmp output drops EXIF data. CMYK sources stay CMYK in Jpeg and Tiff output and are converted to sRGB through their profile for the other formats. Lossy Jxl output (`-Quality` below 100) stores no ICC profile, so the pixels of a source with one (Display P3, Adobe RGB) are converted to sRGB first and keep their look; `-Quality 100` keeps a profile that matches the pixels. An ICC profile that the colour engine cannot apply (damaged, e.g. cut short, or of an unknown colour space) is left out of every output, as viewers ignore it; before, PNG and lossless Jxl output failed with it and Chrome did not display the Avif. Grey images with a grey ICC profile keep it in Jpeg, Png, Tiff and lossless Jxl output and are converted to sRGB for WebP, Avif, Bmp and Gif, which store grey pixels as RGB; this includes a grey JPEG XL, which ImageMagick reads as RGB. A profile made for other pixels (a grey profile in a colour image, which viewers ignore, or an RGB profile on grey pixels, which browsers apply and Windows rejects) is written with unchanged pixels and kept, except that it is left out of lossless Jxl output, which could not be written with it, and, as a grey profile on colour pixels, out of Avif and Bmp output, which browsers would not show correctly, and out of Jpeg, Png and Tiff output of neutral grey pixels, which these formats store as grey. After a colour conversion, PNG output carries no `icc:*` text chunks naming the source profile. The colours are kept for sources with an ICC profile, as iPhone photos have; a HEIC or AVIF source that signals other primaries than sRGB only through nclx/CICP (e.g. Display P3, BT.2020) is converted without colour conversion. Transparent pixels are placed on white in Jpeg output (paper white for a CMYK image); the other formats keep the alpha channel, also Tiff output of a palette PNG with up to 16 colours. Sources with several frames (animated GIF/WebP, multi-page TIFF, HEIC with several images) are converted from their first frame with a warning; a source ImageMagick reports as damaged (e.g. a truncated JPEG, also one that lacks only its end marker although its pixels are complete, or an animated GIF cut off after its first frame) is converted with the warning `The image may be damaged (<reasons>): <path>`. Returns the written files as `Get-Item` does, so they can be piped into the next cmdlet also when their names contain `[` or `]`. Writing HEIC is not supported (the bundled Magick.NET build has no HEVC encoder).
- `Convert-Image` writes through a temporary file in the target folder, so a failed or stopped (Ctrl+C) conversion leaves neither a truncated file nor the temporary file; file names with `%` and target names up to the file system limit work. It never overwrites the source file or a file written earlier in the same call (also not with `-Force`), compared by file identity, so a junction, a symbolic link, a subst or mapped drive, a UNC path, a short 8.3 name or a case-insensitive volume on Linux do not get around it; `-Force` replaces read-only and hidden files and keeps their attributes when the file cannot be replaced.
- `ConvertTo-Jpeg`, `ConvertTo-Png`, `ConvertTo-WebP`, `ConvertTo-Avif`, `ConvertTo-JpegXL`: Shortcuts for `Convert-Image -Format Jpeg/Png/WebP/Avif/Jxl` with the same parameters minus `-Format` (`ConvertTo-Png` has no `-Quality`). All files of one call, also from the pipeline, go through a single `Convert-Image` call, so duplicate targets are detected and `-WhatIf`, `-ErrorAction`, `-ErrorVariable`, `-OutVariable`, `-PipelineVariable` and `$?` behave like `Convert-Image`. A source already in the target format (e.g. `ConvertTo-Jpeg a.jpg`) needs a `-DestinationPath`; otherwise it gets a `TargetIsSource` error. The shortcuts call the module's own `Convert-Image`, also when the session defines an alias or a function of that name.
- `ConvertFrom-Heic`: Converts HEIC/HEIF images through `Convert-Image` (default format Jpeg) and rejects files without the extension `.heic`, `.heif` or `.hif`, except the files the call writes itself (`Get-ChildItem -Recurse` into a `-DestinationPath` inside the tree).
- All cmdlets report a failed file as non-terminating error with a stable error id (`PathNotFound`, `InvalidWildcardPattern`, `UnsupportedProvider`, `NotHeicFile`, `TargetIsSource`, `DuplicateTarget`, `TargetExists`, `ConfirmationFailed`, `ImageReadFailed`, `ImageWriteFailed`) and the source file as target object (for `PathNotFound`, `InvalidWildcardPattern` and `UnsupportedProvider` the input as given, one error per input): `$?` is `$false` after a failed file, `-ErrorVariable` holds one record per failure and `-ErrorAction Stop` stops at the first one. For a wildcard pattern that matches nothing, `PathNotFound` names a drive or folder that does not exist, a folder part that is a file, or a folder part with wildcards that no folder (or only a hidden one) matches, or, when the folder exists, says that wildcards skip hidden files and, for a pattern with `[` or `]`, that these are wildcard characters and how to match them; a pattern of another provider gets no hint; an invalid pattern is `InvalidWildcardPattern` whether or not a file of that name exists. `ConfirmationFailed` reports a `-Confirm` that the host cannot ask (e.g. `pwsh -NonInteractive`). A `-DestinationPath` that cannot name a folder (`InvalidDestinationPath`, `UnsupportedProvider`, `DestinationNotDirectory`, also for white space only, on Windows for a colon after the drive (`C:\x:y`), and for a junction or symbolic link whose target is missing or that cannot be resolved, e.g. one that points to itself; target object the `-DestinationPath` value) stops the whole call with one terminating error before any file is read, also with `-WhatIf`; `ConvertFrom-Heic` and each shortcut report it with their own name (e.g. `DestinationNotDirectory,ConvertTo-Jpeg`). A destination folder that cannot be created or written to fails each file with `ImageWriteFailed`. A PSDrive created without `-Scope Global` (in a function, at the top of a script run by its path or with `&`, or in another module) cannot be used, because a script module resolves paths in its own session state, which sees only the global drives: a path on such a drive, or a relative input path while the current location is on it, gets `PathNotFound` or `InvalidDestinationPath` with a message that names the drive and its root and suggests `New-PSDrive -Scope Global` or the file system path; also when the drive has the name of a global drive, which the module would otherwise use instead (the message names both roots), and for a drive of another provider the message says that only file system paths are supported. A drive created at the prompt or by a script dot-sourced there is global and works.
- All cmdlets follow the preference variables of their caller (`$WhatIfPreference`, `$ConfirmPreference`, `$ErrorActionPreference`, `$WarningPreference`, `$InformationPreference`, `$VerbosePreference`, `$DebugPreference`) like compiled cmdlets, also when a script or function sets them in its own scope, e.g. a function with `SupportsShouldProcess` called with `-WhatIf`; a common parameter given to the cmdlet wins.
- `Get-ImageInfo`: Returns format, dimensions, orientation, camera make/model, date taken and file size of HEIC/HEIF and other images; `-Path` with wildcards or `-LiteralPath`, folders are skipped; an image without orientation tag is reported as `TopLeft`; a damaged image (e.g. a truncated JPEG) gets the same warning as in `Convert-Image`; a file given twice is described once. The objects (`PSImageConverter.ImageInfo`) carry a `PSPath` property, hidden from the default view (`Export-Csv`, `ConvertTo-Json` and `Select-Object *` include it; `Select-Object -ExcludeProperty PSPath` leaves it out), so they can be piped into the conversion cmdlets (`Get-ImageInfo *.heic | Where-Object Width -GT 4000 | ConvertTo-Jpeg`); cmdlets that take `-Path` by property name, such as `Get-Item`, bind their `Path` property as a wildcard pattern instead.
- Bundles Magick.NET (Q8, AnyCPU) for Windows (x64, arm64), Linux (x64, arm64, musl-x64) and macOS (x64, arm64). The libraries are downloaded from nuget.org at build time by the `Get_MagickNet` build task.
- Requires PowerShell 7.4 or later; the native library is loaded through the same DllImport resolver on every platform, also when several runspaces (`Start-ThreadJob`, `ForEach-Object -Parallel`) import the module at the same time.
- Sampler build pipeline with GitHub Actions: test matrix (PowerShell 7 on Windows, Linux and macOS) and publishing to the PowerShell Gallery from `main` via the `release` environment. After a release, `Create_ChangeLog_GitHub_PR` opens a pull request with the CHANGELOG update.
- Every push to `dev` publishes a pre-release (`<version>-previewNNNN`) to GitHub and the PowerShell Gallery through the Sampler workflow `publish_prerelease`.

FileList

Version History

Version Downloads Last updated
0.2.0-previe... (current version) 6 10/18/2026