├── BWben.jpeg ├── ExampleOutput.png ├── README.md ├── asciiPictureGenerator.ipynb ├── ben.jpeg └── textben.txt /BWben.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benWindsorCode/asciiConverter/e93e0dfef9c47fcfc228fbb68d65bbe80ae2ca75/BWben.jpeg -------------------------------------------------------------------------------- /ExampleOutput.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benWindsorCode/asciiConverter/e93e0dfef9c47fcfc228fbb68d65bbe80ae2ca75/ExampleOutput.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Ascii Image Converter 2 | A simple jupyter notebook to take a small image (should be around 3cmx5cm), convert it to only black and white pixels and then turn this into a text file represented by '.' and ' ' 3 | 4 | # Running 5 | Follow along the python notebook file, and call the convertFile function on a jpeg of your choosing. 6 | 7 | # Example output 8 | For example here is the script run on my github profile picture: 9 | 10 | 11 | ![Ben Ascii](./ExampleOutput.png) 12 | -------------------------------------------------------------------------------- /asciiPictureGenerator.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Ascii Image Converter\n", 8 | "In this notebook we create a simple python script to convert an image into 'ascii art', which in this case means we represent the image as '.' and ' ' depending on if the pixel is on average dark or not." 9 | ] 10 | }, 11 | { 12 | "cell_type": "code", 13 | "execution_count": 14, 14 | "metadata": {}, 15 | "outputs": [], 16 | "source": [ 17 | "import imageio\n", 18 | "import numpy as np" 19 | ] 20 | }, 21 | { 22 | "cell_type": "markdown", 23 | "metadata": {}, 24 | "source": [ 25 | "We first write a function to convert each pixel in a row to black or white depending on if the mean of the pixels is greater than half of the $0-255$ range. The file will be read by imageio as an array where each row is the row of pixels, and each pixel is itself an array of the $[R,G,B]$ values. So its in effect a 3D array, but better to think of as a 2D array where each point is a single pixel." 26 | ] 27 | }, 28 | { 29 | "cell_type": "code", 30 | "execution_count": 15, 31 | "metadata": {}, 32 | "outputs": [], 33 | "source": [ 34 | "def convertRowToBW(row):\n", 35 | " newRow=[]\n", 36 | " for pixel in row:\n", 37 | " avg=(int(pixel[0])+int(pixel[1])+int(pixel[2]))/3\n", 38 | " if avg>125:\n", 39 | " newRow.append([255,255,255])\n", 40 | " else:\n", 41 | " newRow.append([0,0,0])\n", 42 | " return newRow" 43 | ] 44 | }, 45 | { 46 | "cell_type": "markdown", 47 | "metadata": {}, 48 | "source": [ 49 | "Next we write a function to apply this row operation to the whole image." 50 | ] 51 | }, 52 | { 53 | "cell_type": "code", 54 | "execution_count": 16, 55 | "metadata": {}, 56 | "outputs": [], 57 | "source": [ 58 | "def convertFileToBW(file):\n", 59 | " newFile=[]\n", 60 | " for row in file:\n", 61 | " newFile.append(convertRowToBW(row))\n", 62 | " return np.array(newFile).astype('uint8')" 63 | ] 64 | }, 65 | { 66 | "cell_type": "markdown", 67 | "metadata": {}, 68 | "source": [ 69 | "Given the above output, we now need to take this a row of black or white pixels and convert it into a string of '.' and ' '" 70 | ] 71 | }, 72 | { 73 | "cell_type": "code", 74 | "execution_count": 17, 75 | "metadata": {}, 76 | "outputs": [], 77 | "source": [ 78 | "def convertTextRow(row):\n", 79 | " newRow=\"\"\n", 80 | " for pixel in row:\n", 81 | " if pixel[0]==0:\n", 82 | " newRow=newRow+\".\"\n", 83 | " else:\n", 84 | " newRow=newRow+\" \"\n", 85 | " return newRow" 86 | ] 87 | }, 88 | { 89 | "cell_type": "markdown", 90 | "metadata": {}, 91 | "source": [ 92 | "As above, we also write a function to take this row operation and apply it to a whole black and white file. " 93 | ] 94 | }, 95 | { 96 | "cell_type": "code", 97 | "execution_count": 18, 98 | "metadata": {}, 99 | "outputs": [], 100 | "source": [ 101 | "def convertTextFile(blackAndWhiteFile):\n", 102 | " newText = \"\"\n", 103 | " for row in blackAndWhiteFile:\n", 104 | " newText=newText+convertTextRow(row)+'\\n'\n", 105 | " return newText" 106 | ] 107 | }, 108 | { 109 | "cell_type": "markdown", 110 | "metadata": {}, 111 | "source": [ 112 | "Finally we bring these file operations together into one function which we can feed a file name to. We do this by simply first applying our black and white converstion function, then applying our text conversion function, and saving the output to a text file. We also save the intermediary step of the black and white file to allow comparison." 113 | ] 114 | }, 115 | { 116 | "cell_type": "code", 117 | "execution_count": 24, 118 | "metadata": {}, 119 | "outputs": [], 120 | "source": [ 121 | "def convertFile(fileName):\n", 122 | " file=imageio.imread(fileName)\n", 123 | " BWFile=convertFileToBW(file)\n", 124 | " imageio.imwrite('BW'+fileName, BWFile)\n", 125 | " strippedName=fileName.split('.')[0]\n", 126 | " textFile=open('text'+strippedName+'.txt', 'wb')\n", 127 | " textFile.write(str.encode(convertTextFile(BWFile)))\n", 128 | " textFile.close()" 129 | ] 130 | }, 131 | { 132 | "cell_type": "code", 133 | "execution_count": 27, 134 | "metadata": {}, 135 | "outputs": [], 136 | "source": [ 137 | "convertFile(\"ben.jpeg\")" 138 | ] 139 | }, 140 | { 141 | "cell_type": "markdown", 142 | "metadata": {}, 143 | "source": [ 144 | "
" 145 | ] 146 | }, 147 | { 148 | "cell_type": "markdown", 149 | "metadata": {}, 150 | "source": [ 151 | "And the text ouput: [Text Output](textben.txt)" 152 | ] 153 | } 154 | ], 155 | "metadata": { 156 | "kernelspec": { 157 | "display_name": "Python 3", 158 | "language": "python", 159 | "name": "python3" 160 | }, 161 | "language_info": { 162 | "codemirror_mode": { 163 | "name": "ipython", 164 | "version": 3 165 | }, 166 | "file_extension": ".py", 167 | "mimetype": "text/x-python", 168 | "name": "python", 169 | "nbconvert_exporter": "python", 170 | "pygments_lexer": "ipython3", 171 | "version": "3.7.1" 172 | } 173 | }, 174 | "nbformat": 4, 175 | "nbformat_minor": 2 176 | } 177 | -------------------------------------------------------------------------------- /ben.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benWindsorCode/asciiConverter/e93e0dfef9c47fcfc228fbb68d65bbe80ae2ca75/ben.jpeg -------------------------------------------------------------------------------- /textben.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | ......... 38 | ............... 39 | ................. 40 | .................... 41 | ...................... 42 | ....................... 43 | ......................... 44 | ............. ........ 45 | ............ ...... . 46 | .......... ..... . 47 | ............ ..... . 48 | ............. .... .. 49 | .............. .... . 50 | ............... .... .. 51 | .............. .... ... 52 | ............... .... ... 53 | ................... .... .. ... 54 | .................... ..... .. .. ... 55 | ..................... .... . .. .... 56 | ...................... ...... .. ..... 57 | ......................... .... .. .... 58 | ...................... ...... .. .... 59 | ...................... .. .. ....... 60 | ...................... ....... 61 | ..................... ....... 62 | .................... ....... 63 | .................... ........ 64 | .............. ..... ........ 65 | .............. ...... ........ 66 | ............. ..... ........ 67 | .................. ......... 68 | ............. .... ......... 69 | ............ ...... ......... 70 | .......... ............ ......... 71 | ................. ......... 72 | ................. .......... 73 | ................ .......... 74 | ................ .......... 75 | ................. .......... 76 | .................... .......... 77 | ..................... .......... 78 | ....................... . .......... 79 | ......................... .. ........... 80 | ........................ ... ........... 81 | .......................... ... ........... 82 | ........................... .... ........... 83 | ........................... ....... ........... 84 | ........................... ........ ........... 85 | ............................ ........... ........... 86 | ............................. ............ ............ 87 | ............................. ............... ............ 88 | .......................... . .................. ............ 89 | .......................... ..................... ............ 90 | ......................... ........................ ............ 91 | ....................... .......................... ............ 92 | ....................... ......................................... 93 | ........................ .......................................... 94 | ....................... ........................................... 95 | ........................ ............................................. 96 | ........................ ............................................... 97 | ........................................................................... 98 | ........................................................................... 99 | ........................................................................... 100 | ........................................................................... 101 | ........................................................................... 102 | ........................................................................... 103 | ........................................................................... 104 | ........................................................................... 105 | ........................................................................... 106 | ........................................................................... 107 | ........................................................................... 108 | ........................................................................... 109 | ........................................................................... 110 | ........................................................................... 111 | ........................................................................... 112 | ........................................................................... 113 | ........................................................................... 114 | --------------------------------------------------------------------------------