Created
April 13, 2014 03:11
-
-
Save cdiener/10567484 to your computer and use it in GitHub Desktop.
asciinator.py now with documentation
This file contains 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
# This line imports the modules we will need. The first is the sys module used | |
# to read the command line arguments. Second the Python Imaging Library to read | |
# the image and third numpy, a linear algebra/vector/matrix module. | |
import sys; from PIL import Image; import numpy as np | |
# This is a list of characters from low to high "blackness" in order to map the | |
# intensities of the image to ascii characters | |
chars = np.asarray(list(' .,:;irsXA253hMHGS#9B&@')) | |
# Check whether all necessary command line arguments were given, if not exit and show a | |
# usage hint. Since the original comment will also be counted as argument we need 4. | |
if len(sys.argv) != 4: print( 'Usage: ./asciinator.py image scale factor' ); sys.exit() | |
# Get some important constants like the filename f, the image size scaling SC and a | |
# intensity correction factor from the command line arguments. The WCF is a width correction | |
# factor we will use since most font characters are higher than wide. | |
f, SC, GCF, WCF = sys.argv[1], float(sys.argv[2]), float(sys.argv[3]), 7/4 | |
# This line opens the image | |
img = Image.open(f) | |
# here we set the new size of the image. The whole image is scaled by the scale factor given | |
# in the command line arguments and we also correct the image with the width correction factor | |
# so that the resulting asciii image has approximately the same aspect ratio as the original | |
# image. | |
S = ( round(img.size[0]*SC*WCF), round(img.size[1]*SC) ) | |
# Here we resize the image and add up the rgb values of the image to get the overall intensity | |
# values for each pixel. | |
img = np.sum( np.asarray( img.resize(S) ), axis=2) | |
# Here we scale the smallest intensity value to zero | |
img -= img.min() | |
# We divide the intensity values by it maximum so all intensities are now between 0 and 1. We invert | |
# the intensity scale by subtracting it from one, so that the whitest pixels map to the space character | |
# and the darkest pixels to the @ character. The now scaled intensities are now raised to the power of the | |
# intensity correction factor GCF which alters the intensity histogram of the image and, thus, gives some | |
# some freedom to counteract very dark or light images. A CGF of 1 gives the original pixel intensities. | |
# Finally the scaled intensities are multiplied with the biggest index of the character array chars (n-1) | |
# and, later, truncated to int which basically maps every intensity value of the original image to an index | |
# of the ascii character array. | |
img = (1.0 - img/img.max())**GCF*(chars.size-1) | |
# Here we assemble and print our ascii art. The image is truncated to int and the entire image matrix is passed | |
# as an index to the character array. This is possible because numpy actually allows indices to be vectors or matrices | |
# where the output will have the same dimensions of the matrix "filtered" by the indexed vector. For example, if | |
# | |
# | |
# v = array(['a', 'b', 'c', 'd']) and M = array( [[0, 1], it follows that v[M] = [['a', 'b'], | |
# [2, 3]] ) ['c', 'd']] | |
# | |
# In the inner generator we combine the characters of each row (r) of the now ascii-mapped image to a single string | |
# and in the outer join we combine all of the row characters by gluing them with together with newline characters. | |
# All of that is printed and done :) | |
print( "\n".join( ("".join(r) for r in chars[img.astype(int)]) ) ) |
Traceback (most recent call last):
File "C:\Users\martijn\Documents\GitHub\datbot\cogs\image.py", line 34, in image_to_ascii
img = np.sum( np.asarray( img.resize(S) ), axis=2)
File "D:\Program_Files\python_3.6\lib\site-packages\numpy\core\fromnumeric.py", line 1848, in sum
out=out, **kwargs)
File "D:\Program_Files\python_3.6\lib\site-packages\numpy\core\_methods.py", line 32, in _sum
return umr_sum(a, axis, dtype, out, keepdims)
ValueError: 'axis' entry is out of bounds
To give a bit of context here, I was splitting a gif into separate frames and saved them as png. Then I opened them, and tried to ascii all of them separately, but the first one already gave this error.
Sorry, Github does not notify of comments on gists :(
@DkOuvE No I haven't seen that one before :/
@Martmists is your image black and white by any chance or use some palette? This might require some adjustments.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
By any chance, do you know about this error?
ValueError: image has wrong mode