Last active
June 24, 2019 16:32
-
-
Save Halkcyon/32a68ea8e7b1fdcf11a80e9026751cb0 to your computer and use it in GitHub Desktop.
Converts image file supported by GDI+ to an ASCII representation.
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
#TODO: Add support for URIs | |
function Convert-ImageToAscii { | |
[Alias('i2a')] | |
[OutputType([string])] | |
[CmdletBinding()] | |
param( | |
[Parameter(Mandatory, Position = 0, ValueFromPipeline)] | |
[ValidateScript({ $PSItem.Exists -and | |
$PSItem.Extension -in '.bmp', '.gif', '.jpeg', '.jpg', '.png', '.tiff' })] | |
[System.IO.FileInfo] | |
$Path, | |
[Parameter(Position = 1)] | |
[ValidateSet('Low', 'Mid', 'High')] | |
[string] | |
$Resolution = 'Low', | |
[Parameter(Mandatory, ParameterSetName = 'SetDimensionsManually')] | |
[ValidateRange(1, [int]::MaxValue)] | |
[int] | |
$Width, | |
[Parameter(Mandatory, ParameterSetName = 'SetDimensionsManually')] | |
[ValidateRange(1, [int]::MaxValue)] | |
[int] | |
$Height, | |
[Parameter(ParameterSetName = 'SetDimensionsAutomatically')] | |
[switch] | |
$FitConsoleHeight, | |
[switch] | |
$Invert | |
) | |
begin { | |
try { | |
& { | |
$ErrorActionPreference = 'Stop' | |
[void][Drawing.Image] | |
} | |
} | |
catch { | |
Add-Type -AssemblyName System.Drawing | |
} | |
$symbols = $(if ($Invert.IsPresent) { | |
@{ | |
Low = '@#+. ' | |
Mid = '@%#*+:,. ' | |
High = '@%#omCXxt?+~;:,. ' | |
} | |
} | |
else { | |
@{ | |
Low = ' .+#@' | |
Mid = ' .,:+*#%@' | |
High = ' .,:;~+?txXCmo#%@' | |
} | |
})[$Resolution] | |
} | |
process { | |
try { | |
$img = [Drawing.Image]::FromFile($Path.FullName) | |
[int]$w, [int]$h = switch ($PSCmdlet.ParameterSetName) { | |
SetDimensionsManually { | |
($Width / 2), $Height | |
} | |
SetDimensionsAutomatically { | |
@(($Host.UI.RawUI.WindowSize.Height * ($img.Width / $img.Height)) | |
($Host.UI.RawUI.WindowSize.Height - 4)) | |
} | |
default { | |
@(($Host.UI.RawUI.WindowSize.Width / 2 - 1) | |
($Host.UI.RawUI.WindowSize.Width / 2 / ($img.Width / $img.Height))) | |
} | |
} | |
$bmp = [Drawing.Bitmap]::new($w, $h) | |
$bmp.SetResolution($img.HorizontalResolution, $img.VerticalResolution) | |
$graphics = [Drawing.Graphics]::FromImage($bmp) | |
$graphics.CompositingMode = [Drawing.Drawing2D.CompositingMode]::SourceCopy | |
$graphics.CompositingQuality = [Drawing.Drawing2D.CompositingQuality]::HighQuality | |
$graphics.InterpolationMode = [Drawing.Drawing2D.InterpolationMode]::HighQualityBicubic | |
$graphics.SmoothingMode = [Drawing.Drawing2D.SmoothingMode]::HighQuality | |
$graphics.PixelOffsetMode = [Drawing.Drawing2D.PixelOffsetMode]::HighQuality | |
$rec = [Drawing.Rectangle]::new(0, 0, $w, $h) | |
$wrapMode = [Drawing.Imaging.ImageAttributes]::new() | |
$wrapMode.SetWrapMode([Drawing.Drawing2D.WrapMode]::TileFlipXY) | |
$graphics.DrawImage($img, $rec, 0, 0, $img.Width, $img.Height, [Drawing.GraphicsUnit]::Pixel, $wrapMode) | |
-join $(foreach ($y in 0..($bmp.Height-1)) { | |
foreach ($x in 0..($bmp.Width-1)) { | |
$p = $bmp.GetPixel($x, $y) | |
"$($symbols[[Math]::Floor((($p.R+$p.G+$p.B)/3)/(256/$symbols.Length))])" * 2 | |
} | |
"`n" | |
}) | |
} | |
finally { | |
if ($null -ne $wrapMode) { $wrapMode.Dispose() } | |
if ($null -ne $graphics) { $graphics.Dispose() } | |
if ($null -ne $bmp) { $bmp.Dispose() } | |
if ($null -ne $img) { $img.Dispose() } | |
} | |
} | |
<# | |
.SYNOPSIS | |
Convert image to ascii. | |
.DESCRIPTION | |
Convert any image to ascii picture by representing each pixels grayscale value as an ascii character. | |
The higher the grayscale value the more space the corresponding ascii character fills. Before being | |
processed the image will be cropped in memory to fit the consoles width or height. | |
.PARAMETER Path | |
The path to the image to process. | |
.PARAMETER Resolution | |
The amount of different ascii characters the grayscale values will be assigned to. The bigger the | |
console window and the smaller the font size a higher resolution tends to look better when the image | |
is also of high resolution. | |
.PARAMETER Width | |
Set the width of the output ascii picture manually. | |
.PARAMETER Height | |
Set the height of the output ascii picture manually. | |
.PARAMETER FitConsoleHeight | |
Whether the output ascii picture should fit the console height instead of width. Only applicable if | |
width and height are not explicitly specified. | |
.PARAMETER Invert | |
Whether the output ascii picture should be inverted. Use this on light console backgrounds | |
for better results. | |
.INPUTS | |
System.IO.FileInfo | |
System.String | |
System.Int32 | |
.OUTPUTS | |
System.String | |
.COMPONENT | |
GDI+ | |
.EXAMPLE | |
Convert-ImageToAscii C:\Users\Bobby\Pictures\bobby-fischer.jpg | |
.EXAMPLE | |
Convert-ImageToAscii -Path C:\Users\Bobby\Pictures\bobby-fischer.jpg -Resolution Mid -FitConsoleHeight | |
.EXAMPLE | |
Convert-ImageToAscii -Path C:\Users\Bobby\Pictures\bobby-fischer.jpg -Width 120 -Height 80 -Invert | |
#> | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment