Skip to content

Instantly share code, notes, and snippets.

@Halkcyon
Last active June 24, 2019 16:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Halkcyon/32a68ea8e7b1fdcf11a80e9026751cb0 to your computer and use it in GitHub Desktop.
Save Halkcyon/32a68ea8e7b1fdcf11a80e9026751cb0 to your computer and use it in GitHub Desktop.
Converts image file supported by GDI+ to an ASCII representation.
#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