Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use the config file to control the script #31

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions about/Authors/carson.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.. csv-table:: Merge-History
:header: Date, Type ,Description
:widths: 10, 10, 100

2020-01-14, config, "use config.yaml to control the script"
118 changes: 84 additions & 34 deletions asciify.py
Original file line number Diff line number Diff line change
@@ -1,91 +1,141 @@
from PIL import Image
import os
from math import ceil
from pathlib import Path
import yaml # pip install pyyaml
import urllib.request

ASCII_CHARS = ['.',',',':',';','+','*','?','%','S','#','@']
ASCII_CHARS = ASCII_CHARS[::-1]
ASCII_CHARS: list

PRINT_CONSOLE_FLAG: bool

'''
method resize():
- takes as parameters the image, and the final width
- resizes the image into the final width while maintaining aspect ratio
'''
def resize(image, new_width=100):
(old_width, old_height) = image.size
aspect_ratio = float(old_height)/float(old_width)


def resize(image, new_width):
old_width, old_height = image.size
aspect_ratio = float(old_height) / float(old_width)
new_height = int(aspect_ratio * new_width)
new_dim = (new_width, new_height)
new_dim = new_width, new_height
new_image = image.resize(new_dim)
return new_image


'''
method grayscalify():
method gray_scalify():
- takes an image as a parameter
- returns the grayscale version of image
'''
def grayscalify(image):


def gray_scarify(image):
return image.convert('L')


'''
method modify():
- replaces every pixel with a character whose intensity is similar
'''
def modify(image, buckets=25):


def modify(image):
initial_pixels = list(image.getdata())
new_pixels = [ASCII_CHARS[pixel_value//buckets] for pixel_value in initial_pixels]
buckets = ceil(255 / len(ASCII_CHARS))
new_pixels = [ASCII_CHARS[(pixel_value // buckets)] for pixel_value in initial_pixels]
return ''.join(new_pixels)


'''
method do():
- does all the work by calling all the above functions
'''
def do(image, new_width=100):
image = resize(image)
image = grayscalify(image)


def do(image, new_width):
image = resize(image, new_width)
image = gray_scarify(image)

pixels = modify(image)
len_pixels = len(pixels)

# Construct the image from the character list
new_image = [pixels[index:index+new_width] for index in range(0, len_pixels, new_width)]
new_image = [pixels[index:index + new_width] for index in range(0, len_pixels, new_width)]

return '\n'.join(new_image)


'''
method runner():
- takes as parameter the image path and runs the above code
- handles exceptions as well
- provides alternative output options
'''
def runner(path):
image = None


def runner(src_img_path: Path, output_path: Path, new_width: int):
try:
image = Image.open(path)
except Exception:
print("Unable to find image in",path)
#print(e)
image = Image.open(src_img_path)
except FileNotFoundError as e:
print(f"Unable to find image in. {str(e)}")
return
image = do(image)
image = do(image, new_width)

# To print on console
print(image)
if PRINT_CONSOLE_FLAG:
print(image)

# Else, to write into a file
# Note: This text file will be created by default under
# the same directory as this python file,
# NOT in the directory from where the image is pulled.
f = open('img.txt','w')
f.write(image)
f.close()
with open(str(output_path), 'w') as f:
f.write(image)
os.startfile(output_path)


'''
method main():
- reads input from console
- profit
'''
if __name__ == '__main__':
import sys
import urllib.request
if sys.argv[1].startswith('http://') or sys.argv[1].startswith('https://'):
urllib.request.urlretrieve(sys.argv[1], "asciify.jpg")
path = "asciify.jpg"


def load_setting_from_config(config_path: str) -> tuple:
with open(config_path, 'r', encoding='utf-8') as f:
config = yaml.load(f.read(), Loader=yaml.SafeLoader)
input_dict = config.get(Path(__file__).stem.upper())
src_img_path = input_dict['SRC_IMG_PATH']
download_dir = Path('./temp')
os.makedirs(download_dir, exist_ok=True)
if src_img_path.startswith('http://') or src_img_path.startswith('https://'):
img_path = download_dir.joinpath(Path(src_img_path).name)
urllib.request.urlretrieve(src_img_path, img_path)
input_dict['SRC_IMG_PATH'] = img_path
else:
path = sys.argv[1]
runner(path)
input_dict['SRC_IMG_PATH'] = Path(input_dict['SRC_IMG_PATH'])
global PRINT_CONSOLE_FLAG, ASCII_CHARS
PRINT_CONSOLE_FLAG = input_dict['PRINT_CONSOLE']
ASCII_CHARS = eval(input_dict['ASCII_CHARS'])
return input_dict['SRC_IMG_PATH'], Path(input_dict['OUTPUT_PATH']), input_dict.get('NEW_WIDTH', 100)


if __name__ == '__main__':
from argparse import ArgumentParser, RawTextHelpFormatter

script_description = '\n'.join([desc for desc in
['\n',
f'python asciify.py --help',
f'python asciify.py',
f'python asciify.py [CONFIG.YAML]',
f'\tpython asciify.py -c config/config.yaml',
]])
arg_parser = ArgumentParser(description='Convert Images into ASCII Art',
usage=script_description, formatter_class=RawTextHelpFormatter)

arg_parser.add_argument('-c', '--config', dest='config', default='config/config.yaml', help="input the path of ``config.yaml``")
g_args = arg_parser.parse_args()
_src_img_path, _output_path, _new_width = load_setting_from_config(g_args.config)
runner(_src_img_path, _output_path, _new_width)
3 changes: 3 additions & 0 deletions config/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
You can decide which ``config.yaml`` to use through the CLI(Command-Line Interface).

.. note:: see more: ``python asciify.py --help``
8 changes: 8 additions & 0 deletions config/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
ASCIIFY:
SRC_IMG_PATH: octocat.png # it can from the Online, for example: http://p1.pstatp.com/large/pgc-image/c3b90be2c32749d3b744f1e322da8738
OUTPUT_PATH: temp/img.txt
NEW_WIDTH: 200 # Height will be determined by width (equivalent scaling)

ASCII_CHARS: "['.', ',', ':', ';', '+', '*', '?', '%', 'S', '#', '@', '[', ']', '|', 'A', 'B', 'C', 'D']"

PRINT_CONSOLE: False # print console or not