Compare commits

..

2 Commits

Author SHA1 Message Date
6cb6d15820 made it work better 2017-12-03 20:46:46 -05:00
6e67a63d73 added brail and animated gif support 2017-12-03 20:46:10 -05:00
2 changed files with 363 additions and 295 deletions

View File

@ -16,6 +16,7 @@ import module
from tools import web from tools import web
ASCII_CHARS = "$@%#*+=-:. " ASCII_CHARS = "$@%#*+=-:. "
BRAIL_CHARS = "⠿⠾⠼⠸⠰⠠ "
HEADERS = {'User-Agent': 'Gimme the ascii.'} HEADERS = {'User-Agent': 'Gimme the ascii.'}
@ -48,21 +49,22 @@ def scale_image(image, size=(100,100)):
return image return image
def pixels_to_chars(image, reverse=False): def pixels_to_chars(image, scale="ascii"):
""" """
Maps each pixel to an ascii char based on where it falls in the range Maps each pixel to an ascii char based on where it falls in the range
0-255 normalized to the length of ASCII_CHARS. 0-255 normalized to the length of ASCII_CHARS.
""" """
range_width = int(255 / len(ASCII_CHARS)) + (255 % len(ASCII_CHARS) > 0) scales = {"ascii": ASCII_CHARS,
"ascii_reverse": "".join(list(reversed(ASCII_CHARS))),
"brail": BRAIL_CHARS,
"brail_reverse": "".join(list(reversed(BRAIL_CHARS)))}
range_width = int(255 / len(scales[scale])) + (255 % len(scales[scale]) > 0)
pixels = list(image.getdata()) pixels = list(image.getdata())
chars = [] chars = []
for pixel in pixels: for pixel in pixels:
if reverse:
index = -int(pixel/range_width)-1
else:
index = int(pixel/range_width) index = int(pixel/range_width)
chars.append(ASCII_CHARS[index]) chars.append(scales[scale][index])
chars = "".join(chars) chars = "".join(chars)
chars = [chars[i:i + image.size[0]] for i in range(0, len(chars), chars = [chars[i:i + image.size[0]] for i in range(0, len(chars),
@ -149,16 +151,71 @@ def colorize(chars, image, code):
return "\n".join(chars) return "\n".join(chars)
def image_to_ascii(image, reverse=False, colors=None): def alpha_composite(front, back):
"""Alpha composite two RGBA images.
Source: http://stackoverflow.com/a/9166671/284318
Keyword Arguments:
front -- PIL RGBA Image object
back -- PIL RGBA Image object
"""
front = np.asarray(front)
back = np.asarray(back)
result = np.empty(front.shape, dtype='float')
alpha = np.index_exp[:, :, 3:]
rgb = np.index_exp[:, :, :3]
falpha = front[alpha] / 255.0
balpha = back[alpha] / 255.0
result[alpha] = falpha + balpha * (1 - falpha)
old_setting = np.seterr(invalid='ignore')
result[rgb] = (front[rgb] * falpha + back[rgb] * balpha * (1 - falpha)) / result[alpha]
np.seterr(**old_setting)
result[alpha] *= 255
np.clip(result, 0, 255)
# astype('uint8') maps np.nan and np.inf to 0
result = result.astype('uint8')
result = Image.fromarray(result, 'RGBA')
return result
def alpha_composite_with_color(image, color=(255, 255, 255)):
"""Alpha composite an RGBA image with a single color image of the
specified color and the same size as the original image.
Keyword Arguments:
image -- PIL RGBA Image object
color -- Tuple r, g, b (default 255, 255, 255)
"""
back = Image.new('RGBA', size=image.size, color=color + (255,))
return alpha_composite(image, back)
def image_to_ascii(image, reverse=False, colors=None, brail=False):
""" """
Reads an image file and converts it to ascii art. Returns a Reads an image file and converts it to ascii art. Returns a
newline-delineated string. If reverse is True, the ascii scale is newline-delineated string. If reverse is True, the ascii scale is
reversed. reversed.
""" """
if image.mode == "RGBA":
image = alpha_composite_with_color(image).convert("RGB")
image = scale_image(image) image = scale_image(image)
image_grey = image.convert('L') # convert to grayscale image_grey = image.convert('L') # convert to grayscale
chars = pixels_to_chars(image_grey, reverse) if reverse:
if brail:
scale = "brail_reverse"
else:
scale = "ascii_reverse"
else:
if brail:
scale = "brail"
else:
scale = "ascii"
chars = pixels_to_chars(image_grey, scale)
if colors: if colors:
chars = colorize(chars, image, colors) chars = colorize(chars, image, colors)
@ -188,7 +245,7 @@ def handle_gif(image, output, reverse=False):
""" """
Handle gifs seperately. Handle gifs seperately.
""" """
image = open_image(args.imagePath) # image = open_image(args.imagePath)
ascii_seq = [] ascii_seq = []
new_image = ascii_to_image(image_to_ascii(image, reverse)) new_image = ascii_to_image(image_to_ascii(image, reverse))
image.seek(1) image.seek(1)
@ -216,11 +273,14 @@ def ascii(bot, trigger):
""" """
Downloads an image and converts it to ascii. Downloads an image and converts it to ascii.
""" """
if not trigger.group(2):
return bot.say()
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument("imagePath") parser.add_argument("imagePath")
parser.add_argument("-r", "--reverse", action="store_true") parser.add_argument("-r", "--reverse", action="store_true")
parser.add_argument("-c", "--color", action="store_true") parser.add_argument("-c", "--color", action="store_true")
parser.set_defaults(reverse=False, color=False) parser.add_argument("-b", "--brail", action="store_true")
parser.add_argument("-a", "--animated", action="store_true")
args = parser.parse_args(trigger.group(2).split()) args = parser.parse_args(trigger.group(2).split())
if args.color: if args.color:
@ -234,7 +294,14 @@ def ascii(bot, trigger):
return return
image = open_image(args.imagePath) image = open_image(args.imagePath)
image_ascii = image_to_ascii(image, args.reverse, args.color) if args.animated:
handle_gif(image, "temp.png", args.reverse)
file = {"file": open("temp.png", "rb")}
res = requests.post("https://uguu.se/api.php?d=upload-tool", files=file)
# print(res.text)
bot.say(res.text)
else:
image_ascii = image_to_ascii(image, args.reverse, args.color, args.brail)
bot.say(image_ascii) bot.say(image_ascii)

View File

@ -28,7 +28,8 @@ def text(html):
def wikt(word): def wikt(word):
bytes = requests.get(uri.format(word)) bytes = requests.get(uri.format(word))
bytes = r_ul.sub('', bytes) # bytes = r_ul.sub('', bytes)
bytes = bytes.text
mode = None mode = None
etymology = None etymology = None