Create a high quality .ico file from a PNG using powershell only

2.6k Views Asked by At

I want to use powershell to download a favicon.png from a website and then convert it into a favicon.ico file that can be used for a desktop shortcut. I already know how to grab the favicon.png from the website using Invoke-WebRequest. I found this code online:

function ConvertTo-Icon {
  param(
    [Parameter(Mandatory=$true)]
    $bitmapPath,
    $iconPath = "$env:temp\newicon.ico"
  )

Add-Type -AssemblyName System.Drawing

if (Test-Path $bitmapPath) {
    $b = [System.Drawing.Bitmap]::FromFile($bitmapPath)
    $icon = [System.Drawing.Icon]::FromHandle($b.GetHicon())
    $file = New-Object System.IO.FileStream($iconPath, 'OpenOrCreate') 
    $icon.Save($file)
    $file.Close()
    $icon.Dispose()

    explorer "/SELECT,$iconpath"
} else { Write-Warning "$BitmapPath does not exist" }
}

The only issue is the resulting .ico file is very low quality: ico vs png (.ico left, .png right)

Is there any way to edit this script and make the resulting file higher quality?

This is part of a script deployed through Intune so it doesn't have the ability to touch on prem resources, otherwise I would simply create the .icos and host them there.

Edit 7/29/22 3:45: Here is my current code:

param (
[string]$name, 
[string]$url, 
[string]$exe,
[string]$ptemp = "c:\temp\png",
[string]$icofold = "c:\Icons\",
[string]$s2url = "https://t2.gstatic.com/faviconV2?client=SOCIAL&type=FAVICON&fallback_opts=TYPE,SIZE,URL&url="
)

#Append Icon URl if needed
if ($url.SubString(0,8) -like 'https://') {}
else { $url = $url.Insert(0,'https://')}
$iconurl = -join($s2url, $url, "&size=64")

#Verify temp directory and save .png
if (Test-Path $ptemp) {}
else { New-Item $ptemp -ItemType Directory}
$temppng = -join($ptemp, "/", $name, ".png")
Invoke-WebRequest -UseBasicParsing -uri $iconurl -outfile $temppng

#Verify Icon Folder exists
if (Test-Path $icofold) {}
else { New-Item $icofold -ItemType Directory}

#Convert to .ico and save
Add-Type -AssemblyName System.Drawing
$iconpath = -join($icofold, $name, ".ico")
    $img = [System.Drawing.Image]::FromFile($temppng)
    $img.Save($iconPath, [System.Drawing.Imaging.ImageFormat]::Icon)
    $img.Dispose()

#Create Shortcut on public Desktop
$desktopDir = Join-Path -Path $env:PUBLIC -ChildPath "Desktop"
$destinationPath = Join-Path -Path $desktopDir -ChildPath "$name.lnk"
$WshShell = New-Object -comObject WScript.Shell
$Shortcut = $WshShell.CreateShortcut($destinationPath)
$Shortcut.TargetPath = $exe
$Shortcut.Arguments = $url
$Shortcut.IconLocation = $iconpath
$Shortcut.Save()

#cleanup
remove-item $temppng
0

There are 0 best solutions below