Skip to content

Instantly share code, notes, and snippets.

@obskyr
Last active June 29, 2018 02:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save obskyr/5706fee71c05ae5db4d77d48c7e32422 to your computer and use it in GitHub Desktop.
Save obskyr/5706fee71c05ae5db4d77d48c7e32422 to your computer and use it in GitHub Desktop.
Prepare lossless images (screenshots, for example) for being posted to Twitter, scaling them reasonably and making sure Twitter will keep them lossless.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import print_function
from __future__ import unicode_literals
"""Turn a lossless image into something in a resolution suitable for Twitter,
and turn down the opacity on a single pixel so Twitter won't convert it.
"""
import glob
import os
import sys
from argparse import ArgumentParser
from PIL import Image
def twittify(image, scale=1):
color_mode = image.palette.mode if image.mode == 'P' else image.mode
has_alpha_channel = color_mode in ('RGBA', 'LA', 'RGBa') or 'transparency' in image.info
image = image.convert('RGBA')
if scale != 1:
image = image.resize((image.width * scale, image.height * scale))
if has_alpha_channel:
has_transparency = next(True for p in image.getdata() if p[3] != 0xFF, False)
else:
has_transparency = False
if not has_transparency:
bottom_right = (image.width - 1, image.height - 1)
# Setting an even slightly translucent opacity on even a single pixel
# makes Twitter keep the image as a lossless PNG.
bottom_right_pixel = image.getpixel(bottom_right)
bottom_right_pixel = bottom_right_pixel[:3] + (254,)
image.putpixel(bottom_right, bottom_right_pixel)
return image
def main(argv):
script_name = os.path.basename(__file__)
parser = ArgumentParser(prog=script_name, add_help=False)
parser.add_argument('-h', '--help', action='help', help="Show this help and exit.")
parser.add_argument('-s', '--scale', metavar="scale", default="1", type=int,
help="Scale the image to [scale] times the size.")
parser.add_argument('files', metavar='file', nargs='+',
help="An image file to twittify.")
args = parser.parse_args(argv)
in_paths = []
for path in args.files:
in_paths += glob.glob(path)
scale = args.scale
exit_status = 0
for in_path in in_paths:
out_path = os.path.splitext(in_path)[0] + '-twitter.png'
try:
image = Image.open(in_path)
except IOError:
print("Error: couldn't open {}.".format(in_path), file=sys.stderr)
exit_status = 1
continue
image = twittify(image, scale)
try:
image.save(out_path)
except IOError:
print("Error: couldn't save to {}.".format(out_path), file=sys.stderr)
exit_status = 1
continue
print("Twittified {} to {}.".format(in_path, out_path))
return exit_status
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment