Skip to content

Instantly share code, notes, and snippets.

@dadatuputi
Created July 9, 2025 22:06
Show Gist options
  • Save dadatuputi/5a7e11e75446cda65420bb17a3c9bcd5 to your computer and use it in GitHub Desktop.
Save dadatuputi/5a7e11e75446cda65420bb17a3c9bcd5 to your computer and use it in GitHub Desktop.
HEIC to JPG Conversion Script
# HEIC to JPG Converter - Send To Version
# Usage: .\script.ps1 -Install (to install to Send To menu)
# .\script.ps1 -Uninstall (to remove from Send To menu)
# .\script.ps1 (normal conversion when called from Send To)
param(
[switch]$Install,
[switch]$Uninstall,
[Parameter(ValueFromRemainingArguments=$true)]
[string[]]$FilePaths
)
# Install mode
if ($Install) {
Write-Host "=== HEIC to JPG Converter Installer ===" -ForegroundColor Cyan
Write-Host ""
# Check for ImageMagick first
try {
$magickPath = (Get-Command magick -ErrorAction Stop).Source
Write-Host "✓ ImageMagick found: $magickPath" -ForegroundColor Green
# Test that it actually works
$version = & magick -version 2>&1 | Select-Object -First 1
Write-Host "✓ ImageMagick working: $version" -ForegroundColor Green
}
catch {
Write-Host "❌ ImageMagick not found in PATH!" -ForegroundColor Red
Write-Host " Please install ImageMagick first:" -ForegroundColor Yellow
Write-Host " winget install ImageMagick.Q8" -ForegroundColor Yellow
Write-Host ""
Read-Host "Press Enter to exit"
exit 1
}
# Check for HEIC support
try {
$formats = & magick -list format 2>&1 | Out-String
if ($formats -match "HEIC.*r") {
Write-Host "✓ HEIC support detected" -ForegroundColor Green
}
else {
Write-Host "⚠ Warning: HEIC support not detected" -ForegroundColor Yellow
Write-Host " Conversion may not work properly" -ForegroundColor Yellow
}
}
catch {
Write-Host "⚠ Could not check HEIC support" -ForegroundColor Yellow
}
# Install to Send To folder
try {
$sendToPath = "$env:APPDATA\Microsoft\Windows\SendTo"
$shortcutPath = Join-Path $sendToPath "Convert HEIC to JPG.lnk"
$scriptPath = $MyInvocation.MyCommand.Path
# Create Send To directory if it doesn't exist
if (-not (Test-Path $sendToPath)) {
New-Item -Path $sendToPath -ItemType Directory -Force | Out-Null
}
# Determine which PowerShell to use
try {
$pwshPath = (Get-Command pwsh -ErrorAction Stop).Source
$powerShellExe = "pwsh.exe"
Write-Host "✓ PowerShell 7+ detected, will use pwsh for better performance" -ForegroundColor Green
}
catch {
$powerShellExe = "powershell.exe"
Write-Host "ℹ Using Windows PowerShell (no parallel processing)" -ForegroundColor Cyan
}
# Create shortcut
$shell = New-Object -ComObject WScript.Shell
$shortcut = $shell.CreateShortcut($shortcutPath)
$shortcut.TargetPath = $powerShellExe
$shortcut.Arguments = "-ExecutionPolicy Bypass -File `"$scriptPath`""
$shortcut.WorkingDirectory = Split-Path $scriptPath
$shortcut.IconLocation = "imageres.dll,70"
$shortcut.Description = "Convert HEIC files to JPG using ImageMagick"
$shortcut.Save()
Write-Host "✓ Shortcut created in Send To menu!" -ForegroundColor Green
Write-Host " Location: $shortcutPath" -ForegroundColor Gray
Write-Host " Using: $powerShellExe" -ForegroundColor Gray
Write-Host ""
Write-Host "Usage:" -ForegroundColor White
Write-Host " 1. Select one or more HEIC files in File Explorer" -ForegroundColor White
Write-Host " 2. Right-click and choose 'Send to' → 'Convert HEIC to JPG'" -ForegroundColor White
Write-Host ""
}
catch {
Write-Host "❌ Failed to create shortcut: $_" -ForegroundColor Red
Read-Host "Press Enter to exit"
exit 1
}
Read-Host "Installation complete! Press Enter to exit"
exit 0
}
# Uninstall mode
elseif ($Uninstall) {
Write-Host "=== HEIC to JPG Converter Uninstaller ===" -ForegroundColor Cyan
Write-Host ""
$sendToPath = "$env:APPDATA\Microsoft\Windows\SendTo"
$shortcutPath = Join-Path $sendToPath "Convert HEIC to JPG.lnk"
# Check if the shortcut exists
if (Test-Path $shortcutPath) {
try {
Remove-Item $shortcutPath -Force
Write-Host "✓ Shortcut removed from Send To menu!" -ForegroundColor Green
Write-Host " Removed: $shortcutPath" -ForegroundColor Gray
}
catch {
Write-Host "❌ Failed to remove shortcut: $_" -ForegroundColor Red
Write-Host " You may need to remove it manually from:" -ForegroundColor Yellow
Write-Host " $shortcutPath" -ForegroundColor Yellow
}
}
else {
Write-Host "ℹ Shortcut not found in Send To menu" -ForegroundColor Yellow
Write-Host " Expected location: $shortcutPath" -ForegroundColor Gray
}
Write-Host ""
Read-Host "Uninstall complete! Press Enter to exit"
exit 0
}
elseif (-not $FilePaths || $FilePaths.Count -eq 0) {
Write-Host "❌ No files specified for conversion!" -ForegroundColor Red
Write-Host "Usage: .\script.ps1 -InputPath <path_to_heic_file>" -ForegroundColor Yellow
Write-Host "Or use the Send To menu after installing the script" -ForegroundColor Yellow
Read-Host "Press Enter to exit"
exit 1
}
# Check for ImageMagick
try {
$magickPath = (Get-Command magick -ErrorAction Stop).Source
Write-Host "✓ Found ImageMagick: $magickPath" -ForegroundColor Green
}
catch {
Write-Host "❌ ImageMagick not found in PATH!" -ForegroundColor Red
Write-Host " Please install ImageMagick and add it to your PATH" -ForegroundColor Yellow
Read-Host "Press Enter to exit"
exit 1
}
# Filter for HEIC files only
$heicFiles = $FilePaths | Where-Object {
(Test-Path $_) -and ([System.IO.Path]::GetExtension($_).ToLower() -eq ".heic")
}
if ($heicFiles.Count -eq 0) {
Write-Host "❌ No HEIC files found in selection" -ForegroundColor Red
Read-Host "Press Enter to exit"
exit 1
}
Write-Host "Found $($heicFiles.Count) HEIC file(s) to convert" -ForegroundColor Cyan
Write-Host ""
# Conversion function
function Convert-HeicFile {
param($inputPath)
$inputFile = Get-Item $inputPath
$outputPath = Join-Path $inputFile.Directory.FullName ($inputFile.BaseName + ".jpg")
try {
Write-Host "Converting: $($inputFile.Name)" -ForegroundColor Yellow
# Check if output exists
if (Test-Path $outputPath) {
Write-Host " → Skipping (JPG already exists)" -ForegroundColor Gray
return @{ Success = $false; Reason = "Already exists"; Input = $inputFile.Name; Output = "" }
}
# Convert using ImageMagick
$process = Start-Process -FilePath $magickPath -ArgumentList "`"$inputPath`"", "`"$outputPath`"" -Wait -PassThru -WindowStyle Hidden
if ($process.ExitCode -eq 0 -and (Test-Path $outputPath)) {
Write-Host " → Success: $($inputFile.BaseName).jpg" -ForegroundColor Green
return @{ Success = $true; Reason = "Converted"; Input = $inputFile.Name; Output = "$($inputFile.BaseName).jpg" }
}
else {
Write-Host " → Failed (ImageMagick error)" -ForegroundColor Red
return @{ Success = $false; Reason = "Conversion failed"; Input = $inputFile.Name; Output = "" }
}
}
catch {
Write-Host " → Error: $_" -ForegroundColor Red
return @{ Success = $false; Reason = "Error: $_"; Input = $inputFile.Name; Output = "" }
}
}
# Convert files (parallel processing for speed)
if ($heicFiles.Count -gt 1 -and $PSVersionTable.PSVersion.Major -ge 7) {
# Use parallel processing in PowerShell 7+
Write-Host "Converting files in parallel..." -ForegroundColor Cyan
$results = $heicFiles | ForEach-Object -Parallel {
# Re-import the function in parallel scope
function Convert-HeicFile {
param($inputPath)
$magickPath = (Get-Command magick).Source
$inputFile = Get-Item $inputPath
$outputPath = Join-Path $inputFile.Directory.FullName ($inputFile.BaseName + ".jpg")
if (Test-Path $outputPath) {
return @{ Success = $false; Reason = "Already exists"; Input = $inputFile.Name; Output = "" }
}
$process = Start-Process -FilePath $magickPath -ArgumentList "`"$inputPath`"", "`"$outputPath`"" -Wait -PassThru -WindowStyle Hidden
if ($process.ExitCode -eq 0 -and (Test-Path $outputPath)) {
return @{ Success = $true; Reason = "Converted"; Input = $inputFile.Name; Output = "$($inputFile.BaseName).jpg" }
}
else {
return @{ Success = $false; Reason = "Conversion failed"; Input = $inputFile.Name; Output = "" }
}
}
Convert-HeicFile $_
} -ThrottleLimit 4
}
else {
# Sequential processing for PowerShell 5.1 or single files
Write-Host "Converting files..." -ForegroundColor Cyan
$results = $heicFiles | ForEach-Object { Convert-HeicFile $_ }
}
# Summary
Write-Host ""
Write-Host "=== Conversion Summary ===" -ForegroundColor Cyan
$successful = $results | Where-Object { $_.Success }
$failed = $results | Where-Object { -not $_.Success }
Write-Host "Total files processed: $($heicFiles.Count)" -ForegroundColor White
Write-Host "Successfully converted: $($successful.Count)" -ForegroundColor Green
Write-Host "Failed/Skipped: $($failed.Count)" -ForegroundColor $(if ($failed.Count -gt 0) { "Yellow" } else { "Green" })
if ($successful.Count -gt 0) {
Write-Host ""
Write-Host "Converted files:" -ForegroundColor Green
$successful | ForEach-Object {
Write-Host " ✓ $($_.Input) → $($_.Output)" -ForegroundColor Green
}
}
if ($failed.Count -gt 0) {
Write-Host ""
Write-Host "Failed/Skipped:" -ForegroundColor Yellow
$failed | ForEach-Object {
Write-Host " ✗ $($_.Input) - $($_.Reason)" -ForegroundColor Yellow
}
}
Write-Host ""
Read-Host "Press Enter to exit"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment