Last active
January 25, 2026 14:30
-
-
Save h8rt3rmin8r/0addbf750d2d6eeb65094bf10bd20ef2 to your computer and use it in GitHub Desktop.
Converts a directory of icon images into a JSON dataset containing metadata, dimensions, and base64 strings (intended for web development usage).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <# | |
| .SYNOPSIS | |
| Converts a directory of icon images into a JSON dataset containing metadata, dimensions, and base64 strings. | |
| .DESCRIPTION | |
| This script iterates through a specified directory of image files. For each file, it generates a custom | |
| PSObject containing the filename, size, dimensions, and a data object with the Base64 string. | |
| The final result is exported to a JSON file. | |
| Requirements: | |
| - .NET Assembly System.Drawing (Standard in Windows PowerShell; requires libgdiplus on Linux/macOS for PS Core). | |
| .PARAMETER Directory | |
| The full or relative path to the directory containing the icon files. | |
| Validation: Path must exist and be a container (directory). | |
| (Belongs to Parameter Set: Default) | |
| .PARAMETER Include | |
| (Optional) A list of file extensions or wildcard patterns to process. | |
| Defaults to: "png", "jpg", "svg", "ico". | |
| Behavior: | |
| - If a string contains wildcards (e.g., "icon_*"), it is used as-is. | |
| - If a string has no wildcards (e.g., "png"), it is treated as an extension (*.png). | |
| (Belongs to Parameter Set: Default) | |
| .PARAMETER Output | |
| (Optional) The full path for the output JSON file. | |
| (Belongs to Parameter Set: Default) | |
| .PARAMETER Help | |
| Displays the full help documentation for this script. | |
| (Belongs to Parameter Set: HelpText) | |
| .EXAMPLE | |
| .\Convert-IconsToJson.ps1 -Directory ".\icons" | |
| Process "png, jpg, svg, ico" files in the icons directory and output to ".\icons.json". | |
| .EXAMPLE | |
| .\Convert-IconsToJson.ps1 -Directory ".\assets" -Include "png", "icon_*" | |
| Process all .png files AND any files starting with "icon_" in the assets directory. | |
| #> | |
| [CmdletBinding(DefaultParameterSetName = 'Default')] | |
| param( | |
| [Parameter( | |
| Mandatory = $true, | |
| Position = 0, | |
| ParameterSetName = 'Default', | |
| HelpMessage = "Path to the icons directory." | |
| )] | |
| [ValidateScript({ | |
| if (Test-Path $_ -PathType Container) { return $true } | |
| throw "The path '$_' does not exist or is not a directory." | |
| })] | |
| [Alias("d")] | |
| [string]$Directory, | |
| [Parameter( | |
| Mandatory = $false, | |
| ParameterSetName = 'Default', | |
| HelpMessage = "File patterns to include (e.g., 'png', 'icon_*')." | |
| )] | |
| [Alias("i")] | |
| [string[]]$Include = @("png", "jpg", "svg", "ico"), | |
| [Parameter( | |
| Mandatory = $false, | |
| ParameterSetName = 'Default', | |
| HelpMessage = "Path for the output JSON file." | |
| )] | |
| [Alias("o")] | |
| [string]$Output, | |
| [Parameter( | |
| Mandatory = $true, | |
| ParameterSetName = 'HelpText', | |
| HelpMessage = "Show script usage and help." | |
| )] | |
| [Alias("h")] | |
| [switch]$Help | |
| ) | |
| BEGIN { | |
| Set-StrictMode -Version Latest | |
| $ErrorActionPreference = "Stop" | |
| # Load System.Drawing for dimension extraction | |
| try { | |
| Add-Type -AssemblyName System.Drawing | |
| } | |
| catch { | |
| Write-Warning "Could not load System.Drawing. Dimension extraction may fail." | |
| } | |
| # MIME Type mapping for common icon formats | |
| $MimeMap = @{ | |
| '7z' = 'application/x-7z-compressed' | |
| 'aac' = 'audio/aac' | |
| 'avi' = 'video/x-msvideo' | |
| 'bmp' = 'image/bmp' | |
| 'css' = 'text/css' | |
| 'csv' = 'text/csv' | |
| 'db' = 'application/octet-stream' | |
| 'doc' = 'application/msword' | |
| 'eot' = 'application/vnd.ms-fontobject' | |
| 'gif' = 'image/gif' | |
| 'gz' = 'application/gzip' | |
| 'gzip' = 'application/gzip' | |
| 'htm' = 'text/html' | |
| 'html' = 'text/html' | |
| 'ico' = 'image/x-icon' | |
| 'jpeg' = 'image/jpeg' | |
| 'jpg' = 'image/jpeg' | |
| 'js' = 'application/javascript' | |
| 'json' = 'application/json' | |
| 'm3u8' = 'application/vnd.apple.mpegurl' | |
| 'm4a' = 'audio/mp4' | |
| 'mkv' = 'video/x-matroska' | |
| 'mp3' = 'audio/mpeg' | |
| 'mp4' = 'video/mp4' | |
| 'pdf' = 'application/pdf' | |
| 'php' = 'text/x-php' | |
| 'png' = 'image/png' | |
| 'psd' = 'image/vnd.adobe.photoshop' | |
| 'rar' = 'application/x-rar-compressed' | |
| 'sql' = 'application/sql' | |
| 'sqlite' = 'application/x-sqlite3' | |
| 'svg' = 'image/svg+xml' | |
| 'svgz' = 'image/svg+xml' | |
| 'tif' = 'image/tiff' | |
| 'tiff' = 'image/tiff' | |
| 'ttf' = 'font/ttf' | |
| 'txt' = 'text/plain' | |
| 'wav' = 'audio/wav' | |
| 'webm' = 'video/webm' | |
| 'webp' = 'image/webp' | |
| 'woff' = 'application/font-woff' | |
| 'woff2' = 'application/font-woff2' | |
| 'zip' = 'application/zip' | |
| } | |
| } | |
| PROCESS { | |
| switch ($PSCmdlet.ParameterSetName) { | |
| 'HelpText' { | |
| if ($Help) { | |
| ## We have to use the $Help variable to get around PS analysis warnings in VS Code | |
| Get-Help $MyInvocation.MyCommand.Path -Full | |
| return | |
| } | |
| } | |
| 'Default' { | |
| try { | |
| # 1. Resolve and Normalize Paths | |
| $RootItem = Get-Item -Path $Directory | |
| $ResolvedPath = $RootItem.FullName | |
| $DirName = $RootItem.Name | |
| if ([string]::IsNullOrWhiteSpace($Output)) { | |
| $Output = Join-Path -Path $PWD -ChildPath "$DirName.json" | |
| } else { | |
| $OutputInfo = [System.IO.FileInfo]$Output | |
| # -LiteralPath ensures paths with brackets [] are handled correctly | |
| if (-not (Test-Path -LiteralPath $OutputInfo.DirectoryName -PathType Container -ErrorAction SilentlyContinue)) { | |
| New-Item -ItemType Directory -Path $OutputInfo.DirectoryName -Force | Out-Null | |
| } | |
| } | |
| # 2. Normalize Include Patterns | |
| Write-Verbose "Normalizing include patterns..." | |
| $SearchPatterns = $Include | ForEach-Object { | |
| $Item = $_.Trim().ToLower() | |
| if ($Item.Contains('*')) { | |
| $Item | |
| } else { | |
| if ($Item.StartsWith(".")) { "*$Item" } else { "*.$Item" } | |
| } | |
| } | |
| Write-Verbose "Input Directory: $ResolvedPath" | |
| Write-Verbose "Search Patterns: $($SearchPatterns -join ', ')" | |
| Write-Verbose "Output File: $Output" | |
| # 3. Gather Files | |
| Write-Verbose "Scanning directory for files..." | |
| ## Force array to prevent StrictMode errors on count 0 or 1 | |
| $Files = @(Get-ChildItem -Path "$ResolvedPath\*" -Include $SearchPatterns -File) | |
| if ($Files.Count -eq 0) { | |
| Write-Warning "No files found in '$ResolvedPath' matching patterns: $($SearchPatterns -join ', ')" | |
| return | |
| } | |
| Write-Verbose "Found $($Files.Count) files. Beginning processing..." | |
| ## Initialize index counter | |
| $Index = 0 | |
| # 4. Process Files | |
| $IconList = foreach ($File in $Files) { | |
| Write-Verbose "Processing [$Index]: $($File.Name)" | |
| $Ext = $File.Extension.TrimStart('.').ToLower() | |
| $MimeType = if ($MimeMap.ContainsKey($Ext)) { $MimeMap[$Ext] } else { "application/octet-stream" } | |
| $Prefix = "data:$MimeType;base64," | |
| # A. Read Bytes | |
| try { | |
| $Bytes = [System.IO.File]::ReadAllBytes($File.FullName) | |
| $Base64String = [System.Convert]::ToBase64String($Bytes) | |
| } | |
| catch { | |
| Write-Error "Failed to read file '$($File.Name)': $_" | |
| continue | |
| } | |
| # B. Get Dimensions | |
| $Dimensions = $null | |
| try { | |
| $ImageObj = [System.Drawing.Image]::FromFile($File.FullName) | |
| $Dimensions = "{0}x{1}" -f $ImageObj.Width, $ImageObj.Height | |
| } | |
| catch { | |
| Write-Verbose "Could not determine dimensions for '$($File.Name)'." | |
| $Dimensions = "Unknown" | |
| } | |
| finally { | |
| if ($null -ne $ImageObj) { | |
| $ImageObj.Dispose() | |
| } | |
| } | |
| # C. Construct Object (UPDATED STRUCTURE) | |
| [PSCustomObject]@{ | |
| index = $Index++ | |
| title = $File.BaseName | |
| file = [PSCustomObject]@{ | |
| name = $File.Name | |
| extension = $Ext | |
| size = $File.Length | |
| dimensions = $Dimensions | |
| } | |
| data = [PSCustomObject]@{ | |
| prefix = $Prefix | |
| base64 = $Base64String | |
| } | |
| } | |
| } | |
| # 5. Export to JSON | |
| Write-Verbose "Encoding data to JSON..." | |
| $JsonPayload = $IconList | ConvertTo-Json -Depth 10 | |
| Write-Verbose "Writing to disk..." | |
| $JsonPayload | Set-Content -Path $Output -Encoding UTF8 | |
| Write-Host "Success! Processed $($IconList.Count) icons. Data saved to: $Output" -ForegroundColor Green | |
| } | |
| catch { | |
| Write-Error "A fatal error occurred: $_" | |
| } | |
| } | |
| } | |
| } | |
| END { | |
| if ($PSCmdlet.ParameterSetName -eq 'Default') { | |
| Write-Verbose "Script execution completed." | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment