
Powershell Snippets
Shell Scripts
Manipulating Assets as a technical artist.
- Utilizing
- fd and sd
- imagemagick
Improve Assets Naming
From the several game jams, I found group members tend to have bad naming habits, which is common phenomenon among students.
Bad naming could lead to unexpected error in game engine, so I wrote this script to find out all the poorly named assets in our project.
function List-FilesWithCJKCharacters {
Get-ChildItem -Recurse | Where-Object { $_.Name -match "[\p{IsCJKUnifiedIdeographs}]"} | ForEach-Object {
Write-Host (Resolve-Path $_.FullName -Relative)
}
}
function List-FilesWithSpacesInName {
Get-ChildItem -Recurse | Where-Object { $_.Name -match " " } | ForEach-Object {
Write-Host (Resolve-Path $_.FullName -Relative)
}
}
Batch Rename Assets
After finding out what assets are poorly named, I wrote below scripts to batch rename them. As shown by the function name, the three functions have different naming rules.
function Rename-FilesByCreatedTime {
Get-ChildItem -File | ForEach-Object {
$creationTime = $_.CreationTime
$newName = "{0:yy.MM.dd}_{0:HH.mm.ss}{1}" -f $creationTime, $_.Extension
Rename-Item -Path $_.FullName -NewName $newName
}
}
function Rename-FilesBySequence {
Get-ChildItem -File | ForEach-Object {
$newName = "{0:D2}{1}" -f $count++, $_.Extension
Rename-Item -Path $_.FullName -NewName $newName
}
}
function Rename-FilesForUnity {
Get-ChildItem -File | ForEach-Object {
$oldName = $_.Name -replace " ", "_"
$newName = ($oldName -split '_' | ForEach-Object { $_.Substring(0,1).ToUpper() + $_.Substring(1) }) -join '_'
Rename-Item -Path $_.FullName -NewName $newName
}
}
Image Processing
Below are scripts that batch process images to make them better fit game engines like Unity, as suggested by the official document.
# Get image information for a list of files.
# Outputs a table with file names, file types, colorspaces, bit depths, and dimensions.
function Get-ImageInfo {
$imageInfos = @()
# Use ImageMagick to identify image properties and format the output.
magick identify -format "%f %m %[colorspace] %z-bit %wx%h`n" * | ForEach-Object {
$tokens = $_ -split ' '
$imageInfo = [PSCustomObject]@{
FileName = $tokens[0]
FileType = $tokens[1]
Color = $tokens[2]
BitDepth = $tokens[3]
Dimension = $tokens[4]
}
$imageInfos += $imageInfo
}
# Sort and display the image information in a table.
$imageInfos | Sort-Object FileType | Format-Table -AutoSize
}
# Resize images to ensure dimensions are divisible by 4.
# Maintains aspect ratio while resizing.
function Resize-Images4x {
Get-ChildItem -Include "*.png","*.jpg" -Recurse | ForEach-Object {
$file = $_.FullName
# Get dimensions of the image.
$dimensions = $(magick identify -format "%w %h" $file) -split " "
$width = [int]$dimensions[0]
$height = [int]$dimensions[1]
# Initialize new dimensions as old dimensions.
$new_width = $width
$new_height = $height
# Update dimensions only if they are not divisible by 4.
if ($width % 4 -ne 0) {
$new_width = [math]::Ceiling($width / 4) * 4
}
if ($height % 4 -ne 0) {
$new_height = [math]::Ceiling($height / 4) * 4
}
# Overwrite the original files with resized images.
magick mogrify -resize "${new_width}x${new_height}!" $file
}
}
# Crop images to a fixed size of 512x512 pixels while maintaining the center of the original image.
function Crop-ImagesTo512x512 {
Get-ChildItem -Include "*.png","*.jpg","*.webp","*.avif" -Recurse | ForEach-Object {
magick convert -resize 512x512^ -gravity center -extent 512x512 $_.Name "$($_.BaseName)_512x512$($_.Extension)"
}
}
# Generate thumbnails for HDR and EXR images in the webp format with specified settings.
function Generate-HDRIThumbnail {
# Convert HDR and EXR images to webp format with quality and size settings.
mogrify -format webp -quality 60 -resize 960 -set colorspace RGB -colorspace sRGB *.hdr
mogrify -format webp -quality 60 -resize 960 -set colorspace RGB -colorspace sRGB *.exr
}
# Optimize PNG images using the oxipng tool with specified options.
function Optimize-PNGImages {
fd -e png -x oxipng.exe --alpha --zopfli --strip safe
}