Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
added setup.py/restructured directories to reflect.
- Loading branch information
Showing
10 changed files
with
310 additions
and
5 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,7 @@ | ||
*swp | ||
*pyc | ||
test_imgs | ||
build | ||
dist | ||
*egg-info | ||
.pypirc |
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
Empty file.
File renamed without changes.
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
Empty file.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,189 @@ | ||
import colorama | ||
import shutil | ||
import os | ||
from PIL import Image | ||
from PIL import ImageDraw | ||
|
||
class Ascii(): | ||
def __init__(self, in_file): | ||
""" Python ascii image maker """ | ||
|
||
self.letter_densities = '" .`-_\':,;^=+/"|)\\<>)iv%xclrs{*}I?!][1taeo7zjLunT#JCwfy325Fp6mqSghVd4EgXPGZbYkOA&8U$@KHDBWNMR0Q' | ||
|
||
self.from_pic = Image.open(in_file) | ||
self.to_pic = Image.new("RGB", self.from_pic.size, "black") | ||
self.draw = ImageDraw.Draw(self.to_pic) | ||
|
||
self.MAX_W, self.MAX_H = self.from_pic.size | ||
|
||
def word_artify(self, words="#", step=3): | ||
""" create ascii image from word string """ | ||
|
||
words = words.upper() | ||
|
||
h = w = i = 0 | ||
|
||
# skip pixels by `step` amount and place characters around image | ||
while h < self.MAX_H: | ||
while w < self.MAX_W: | ||
# use a string as the art characters | ||
c = words[i] | ||
|
||
# loop around | ||
i = (i+1) % len(words) | ||
|
||
# get the color from the pixel | ||
p = self.from_pic.getpixel((w, h)) | ||
|
||
# insert text based on pixel color | ||
self.draw.text((w, h), c, p) | ||
|
||
w += step | ||
h += step | ||
w = 0 | ||
|
||
self.from_pic.close() | ||
|
||
|
||
def density_artify(self, step=7): | ||
""" | ||
Generates the acsii image where the 'words' are selected based on | ||
the brightness of a pixel. | ||
A brighter pixel will have a character with lower visual density and | ||
a less bright pixel will have a character with high visual density. | ||
""" | ||
|
||
if step < 7: | ||
step = 7 | ||
|
||
h = 0 | ||
w = 0 | ||
|
||
# used for brightness (density) levels | ||
grayscale_img = self.from_pic.convert("L") | ||
|
||
while h < self.MAX_H: | ||
while w < self.MAX_W: | ||
# get brightness value | ||
brightness = 255 - grayscale_img.getpixel((w, h)) | ||
clr = self.from_pic.getpixel((w, h)) | ||
|
||
# select required character from the letter_densities list | ||
char_pos = (brightness/255.0) * (len(self.letter_densities) - 1) | ||
c = self.letter_densities[int(round(char_pos, 0))] | ||
self.draw.text((w, h), c, clr) | ||
|
||
w += step | ||
h += step | ||
w = 0 | ||
|
||
self.from_pic.close() | ||
grayscale_img.close() | ||
|
||
|
||
def terminal_artify(self): | ||
""" covert image to ascii, display in terminal """ | ||
|
||
# all colors are beautiful | ||
acab = [ | ||
[( 0, 0, 0), colorama.Fore.LIGHTBLACK_EX], | ||
[( 0, 0, 255), colorama.Fore.BLUE], | ||
[( 0, 255, 0), colorama.Fore.GREEN], | ||
[(255, 0, 0), colorama.Fore.RED], | ||
[(255, 255, 255), colorama.Fore.WHITE], | ||
[(255, 0, 255), colorama.Fore.MAGENTA], | ||
[( 0, 255, 255), colorama.Fore.CYAN], | ||
[(255, 255, 0), colorama.Fore.YELLOW] | ||
] | ||
|
||
# convert to floats, linearize | ||
# in case more colors are added | ||
acab = [ [[(v/255.0)**2.2 for v in x[0]], x[1]] for x in acab ] | ||
|
||
# needed for Windows operating systems | ||
colorama.init() | ||
|
||
canvas = self.from_pic | ||
current_h, current_w = float(self.MAX_H), float(self.MAX_W) | ||
|
||
# resize to fit current dimensions of terminal | ||
# shutil added get_terminal_size starting in python 3.3 | ||
t_width, t_height = shutil.get_terminal_size() | ||
|
||
if current_h > t_height or current_w > t_width: | ||
# floating point division | ||
scalar = max(current_h/t_height, (current_w*2)/t_width) | ||
current_w = int((current_w*2)/scalar) | ||
current_h = int((current_h)/scalar) | ||
dimensions = current_w, current_h | ||
canvas = self.from_pic.resize(dimensions) | ||
|
||
# used for brightness (density) levels | ||
grayscale_img = canvas.convert("L") | ||
|
||
image = "" | ||
|
||
for h in range(current_h): | ||
for w in range(current_w): | ||
# get brightness value | ||
brightness = grayscale_img.getpixel((w, h))/255.0 | ||
pixel = canvas.getpixel((w, h)) | ||
# getpixel() may return an int, instead of tuple of ints, if the | ||
# source img is a PNG with a transparency layer. | ||
if isinstance(pixel, int): | ||
pixel = (pixel, pixel, 255) | ||
|
||
srgb = [ (v/255.0)**2.2 for v in pixel ] | ||
|
||
# select required character from the letter_densities list | ||
char_pos = brightness * (len(self.letter_densities) - 1) | ||
|
||
color = self._convert_color(srgb, brightness, acab) | ||
image += color + self.letter_densities[int(round(char_pos, 0))] | ||
image += "\n" | ||
|
||
# prints the converted image to terminal | ||
# (remove the last newline) | ||
print(image[:-1] + colorama.Fore.RESET) | ||
|
||
self.from_pic.close() | ||
grayscale_img.close() | ||
|
||
input("Press enter to continue...") | ||
|
||
|
||
####################################### | ||
# Helper Methods # | ||
####################################### | ||
|
||
def _L2_min(self, v1, v2): | ||
""" | ||
euclidian norm in a 2 dimensional space | ||
used for calculating shortest distance | ||
""" | ||
|
||
return (v1[0]-v2[0])**2 + (v1[1]-v2[1])**2 + (v1[2]-v2[2])**2 | ||
|
||
def _convert_color(self, rgb, brightness, acab): | ||
""" convert color using acab data """ | ||
|
||
min_distance = 2 | ||
index = 0 | ||
|
||
for i in range(len(acab)): | ||
tmp = [ v*brightness for v in acab[i][0] ] | ||
distance = self._L2_min(tmp, rgb) | ||
|
||
if distance < min_distance: | ||
index = i | ||
min_distance = distance | ||
|
||
return acab[index][1] | ||
|
||
def save(self, out_file="out.jpg"): | ||
""" save image to file """ | ||
|
||
self.to_pic.save(out_file) | ||
self.to_pic.close() | ||
|
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 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
#!/usr/bin/env python3 | ||
|
||
from setuptools import setup, find_packages | ||
|
||
setup( | ||
name = 'ascii_py', | ||
version = '1.2', | ||
description = 'Make ascii art', | ||
|
||
author = 'ProfOak', | ||
author_email = 'OpenProfOak@gmail.com', | ||
url = 'https://www.github.com/ProfOak/Ascii_py/', | ||
license = 'MIT', | ||
|
||
classifiers = [ | ||
'Development Status :: 5 - Production/Stable', | ||
|
||
'Intended Audience :: End Users/Desktop', | ||
|
||
'License :: OSI Approved :: MIT License', | ||
|
||
'Operating System :: OS Independent', | ||
'Topic :: Games/Entertainment', | ||
'Topic :: Multimedia :: Graphics', | ||
'Topic :: Multimedia :: Graphics :: Editors', | ||
|
||
# This is because shutil.get_terminal_size() was added in 3.3 | ||
'Programming Language :: Python :: 3.3', | ||
'Programming Language :: Python :: 3.4', | ||
'Programming Language :: Python :: 3.5', | ||
], | ||
|
||
keywords = 'ascii art image fun memes', | ||
|
||
install_requires = [ | ||
'colorama', | ||
'Pillow', | ||
], | ||
packages = find_packages(exclude=['Media','ascii_py_gui']), | ||
|
||
entry_points = { | ||
'console_scripts': [ | ||
'ascii_py = ascii_py.main:main' | ||
] | ||
}, | ||
) |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
#!/usr/bin/env python3 | ||
|
||
from setuptools import setup, find_packages | ||
|
||
setup( | ||
name = 'ascii_py_gui', | ||
version = '1.2', | ||
description = 'Make ascii art', | ||
|
||
author = 'ProfOak', | ||
author_email = 'OpenProfOak@gmail.com', | ||
url = 'https://www.github.com/ProfOak/Ascii_py/', | ||
license = 'MIT', | ||
|
||
classifiers = [ | ||
'Development Status :: 5 - Production/Stable', | ||
|
||
'Intended Audience :: End Users/Desktop', | ||
|
||
'License :: OSI Approved :: MIT License', | ||
|
||
'Operating System :: OS Independent', | ||
'Topic :: Games/Entertainment', | ||
'Topic :: Multimedia :: Graphics', | ||
'Topic :: Multimedia :: Graphics :: Editors', | ||
|
||
# This is because shutil.get_terminal_size() was added in 3.3 | ||
# the pypi version of PySide is not compatible with Python 3.5 | ||
'Programming Language :: Python :: 3.3', | ||
'Programming Language :: Python :: 3.4', | ||
], | ||
|
||
keywords = 'ascii art image fun memes', | ||
|
||
install_requires = [ | ||
'colorama', | ||
'Pillow', | ||
'PySide', | ||
], | ||
packages = find_packages(exclude=['Media','ascii_py']), | ||
|
||
entry_points = { | ||
'console_scripts': [ | ||
'ascii_py_gui = ascii_py_gui.main:main' | ||
] | ||
}, | ||
) |