Skip to content

Support dithering with ASCII characters #61

@adrhill

Description

@adrhill

I've taken a brief look into how this is typically done. Usually people define a ramp of ASCII characters to approximate a gray-scale color ramp. In this sense, we can already dither with ASCII characters using the underlying IndirectArray:

using DitherPunk, TestImages, ImageCore, ImageTransformations

img = testimage("fabio_gray_256")
img = imresize(img, ratio=(1//6, 1//3))

ascii_ramp = split(" .:-=+*#%@", "")
cs = Gray.(range(0, 1, length=10)) # match length of ramp

d = dither(img, FloydSteinberg(), cs)
mat = ascii_ramp[d.index]

for r in eachrow(mat)
    println(join(r))
end

which prints the following (make sure your browser window is wide enough):

----::--------::-:-:-::-::-:--------:--=-=-=---:-----:::::-:-:--:-::::::.::.::.:::.::.
-=--::---------::::::::::::------------=--::-=-+=-----=--::-:-:-:-:::::.:.:.::.:.:.:.:
-=--::--------::::::::::::::----------=+++=+=+=-:---:-:-:--::--:-:::-:.:.:.:.:.:.:.:..
=---::-------:::::::::::::::-:-:--:=+==+=-=++++==+==+==--::::::-:-:::.:...:.:.:.:.:.:.
--=-::-:-------::::::::::::-:::--=====##*+======+=-----::-::.:::::::::..:.:.:.:.:.:.:.
-=--::--------:-::::::::-:-:-++=*+*%#*#*****++++++=-=-::-::.::.:-:::::.....:.:.:.:.:.:
-=--:::-----:--:-:-:--:::--=++***#*+++++++++*+=---=-:=:==:-:.:-:::.::.:.:.:.:.:.:.:.:.
=---::-:------:-::::::::-=+++*#*+=--:::-::::--=+==--=-:=-+:::-:::::.:::..:.:.:.:.:.:.:
----::::-:::.:::-:--:-:-=-***--:-:--=+====-::.-:++++-:.:::-:::--::.::::::.:.:.:.:.:..:
-=--::::::::::::::::::--=+=::::--+:.-----:-=-::.:::-::...::::::--=--:-:.:.:.::.:.:.:.:
--=::::::---:-::-:::-:=+=+=:=---::----::::=-:.+..::::.:::.:::::::=--:::::.::.:.:.:.:.:
-=---:::----:-::::-::=++=-=:::.:::==::----:-:-:::.::.::---------:..::::::::..:.:.:::.:
=-=-::::-:=--::-::::=+-=-::::.::-*#*#*+#**#*++**---:-=***+*++=+==:.:::-::::::.:.:..:..
-==-::::------:::---*++-::--:::-=*######%%##%%###########*+++=++=-::.::::::::.::.::.::
------::--=--:-:--=+*+=-=---:-:--+###%##%#%%#%%%%%##%#%#**+++=+=-:::::-:---::::.:.:.:.
-=---:::--==-----+*++-::-:::::::==*###%%#%##%##%#%%######***+++=-.:::-:-::::::-::.:.:.
=-----::--==--=+***+-:-=::.:-:-::=+*######%########%####***+++=+-:..:---==+--:::.:.:.:
--=:-:::---==*+#+#+=-++=:::-:...*+*########%%#%%#%#%%####***++===-.:.:---=----:.:.::..
=-----::--=++=#***-+++=:.:.....-+****#%%%%%#%#%#%#%##%#%#**++----=....:---=-::::::.::.
-=---:::-==+-*+**++*+=-::..:..:=**+++------==+=*#####+-::::::--===:.:..:..::-::::::.:.
-=---::---=+*****+*+*-:::.:....+****+=+#--:+-=-=*##*==++*:-*+--=+===+:..:::-::::-::.:.
=-=---::-=++*++*+**=+=-::::..::=*#%##%****#####+*##*++*+*#**+**+++-++=.:.:::--::-::..:
-=-:-:::-*+#+****#+*=+--::::..:=+*#%%%%%@%%%##*+*##+=++**###****+==#*+...:--:-==::::..
-----::---#*++****+++===-:--:..-+*##%%%%%#%#%#***##*==+**#*##**++=-**-..:::=--=+:-:::.
-=-:--::-=*++*****=++=++-=---:.:=+*##%#%%%#%##***##*+==******++++-=+:...::--+=+---::.:
----:::-=+*+**#**++=+*++-=-....:-=+**######%##***#**+==*****+++==-=...:.:.::=++--:::..
=----::===*+*****+=+*===+=-....::+=+**#*######***%%*+=+++*++++====-....:.:::==-==::::.
-=--:-:-=+#***#*++++-++=+=:.....-=++**#*###*%##=+**++=+*++*+++=====....::.::-----::::.
------:-*#*#*#+*++==*=++=::....::+++++**#**####**+==+++=+==++=====-......:::-:--:::.::
----===**+*+*#***++**+=:::::....-=*++*+*#*********=*+++==+=++==+==:......:::--:-::::.:
=----*+***++******++=---::::.....==*+*+*#*++=--=-=+----=++++==+==-=:.......::-:--:::-:
::=*++=*=++**#***+*==-=:-:::......=++*++***#*****++++++=+++=+===-===--......::-:-:::-:
-=*====++**##**#*+==-+-::::....... .=+++*#****++++==+==+==+===-++====++-=......::.:.::
--*==-=+**#**#**+=====-:-.:..........-=+=**########****+++===-+++====+++*++=..........
:=*+*+**%#####+=+=+++-:-::..:.........-=-=+***####%##**++==-++++==+++=+++++++=......:.
=+++**###*##++=#=+++-:---:.::.:.......:-+=+=+++**++++++=-=++++++++=++++++++++++....:..
**+*#%#***+**+*=*+=::.---.:.::.::......-==+====--------+==++++++++++++=+=++++=++:...::
+###***++*#**+*+---..:::..:::.::......::-+=++++==+****+++*++**+++++*++++++=+======:..:
#***+***##*+**==:-::::.::..:........:.---++++***#********+******++*+*+*++++=+++++++.:.
*****#***+**++-=-:-:::::...::.::.......--=+++++**********#####*+++*******+**+*+++===:.
*%*********+=*-::::::::.:.:.:......:..:::-+**+*+***#***#*#####*+=+#****+**+*++*+*++===
*=#**#***++---:::.:.:.:::....::.:....::.:+*****+*+***#*#*#*#*#++***+++++++*+**+*+*+**+
***#****++=--:=::::.:.:.::..:...:.....:--=********++*****######**+*+*++**+*++**+******

This might be worth adding to the docs.

However, when #60 is implemented, we can go one step further and use font rasterizers like FreeTypeAbstraction.jl to generate tiles from characters, average their color and return ASCII. This would also open up the possibility of supporting colored letters on colored background.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions