Source code for pycharmers.cli.tweetile

# coding: utf-8
import cv2
import os
import sys
import warnings
import argparse
import numpy as np
from PIL import Image

from typing import Any,Tuple
from nptyping import NDArray

from ..utils._colorings import toBLUE,toGREEN
from ..utils.generic_utils import filenaming
from ..utils.monitor_utils import ProgressMonitor

[docs]def tweetile(argv=sys.argv[1:]): """Divide one image into three so that you can tweet beautifully. Args: path (str) : Path to the input image. --quality (int) : The image quality, on a scale from ``1`` (worst) to ``95`` (best). Defaults to ``95``. --loop (int) : How many times gif image loops. Defaults to ``0``. (infinite loop.) Note: When you run from the command line, execute as follows:: $ tweetile path/to/filename.jpg --quality 75 $ tweetile path/to/filename.gif --loop 0 +-----------------------------------------------+-----------------------------------------------+ | Example | +===============================================+===============================================+ | .. image:: _images/cli.tweetile-shingeki1.gif | .. image:: _images/cli.tweetile-shingeki2.gif | + +-----------------------------------------------+ | | .. image:: _images/cli.tweetile-shingeki3.gif | +-----------------------------------------------+-----------------------------------------------+ This movie is from :tw:`@anime_shingeki` .. tweet:: https://twitter.com/anime_shingeki/status/1376196378624282625 """ parser = argparse.ArgumentParser(prog="tweetile", description="Tile one image for tweet.", add_help=True) parser.add_argument("path", type=str, help="Path to the input image.") parser.add_argument("--quality", type=int, default=95, help="The image quality, on a scale from 1 (worst) to 95 (best). Defaults to 95.") parser.add_argument("--loop", type=int, default=0, help="How many times gif image loops. Defaults to 0. (infinite loop.)") args = parser.parse_args(argv) path = args.path quality = args.quality loop = args.loop root,ext = os.path.splitext(path) paths = [filenaming(f"{root}_{i}{ext}") for i in range(1,4)] if ext == ".gif": images_list = [[],[],[]] cap = cv2.VideoCapture(path) frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) monitor = ProgressMonitor(max_iter=frame_count, barname="tweetile") for i in range(1,frame_count+1): is_ok,img_bgr = cap.read() if (not is_ok) or (img_bgr is None): break img_rgb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB) images = divideInto3forTweet(img_rgb) for j in range(len(images_list)): images_list[j].append(images[j]) images[j].save(f"{j}/{i:>03}.png") monitor.report(i) monitor.remove() for images,path in zip(images_list, paths): images[0].save( fp=path, format="gif", save_all=True, append_images=images[1:], loop=loop, ) print(f"Saved gif at {toBLUE(path)}") else: img_arr = np.asarray(Image.open(path).resize(size=(1132, 636), resample=Image.LANCZOS), dtype=np.uint8) images = divideInto3forTweet(img_arr) for img,path in zip(images, paths): img.save(path, quality=quality) print(f"Saved image at {toBLUE(path)}")
[docs]def divideInto3forTweet(img_arr:NDArray[(636,1132,Any), np.uint8]) -> Tuple[Image.Image,Image.Image,Image.Image]: """Divide Image into 3 for Tweet +--------------------------------------------+ | Size | +============================================+ | .. image:: _images/cli.tweetile-size.jpg | +--------------------------------------------+ Args: img_arr (NDArray[(636,1132,Any), np.uint8]): Input image array (RGB) Returns: Tuple[Image.Image,Image.Image,Image.Image]: A tuple of each Image object divided into three. Examples: >>> import cv2 >>> from pycharmers.cli.tweetile import divideInto3forTweet >>> img_bgr = cv2.imread("cli.tweetile-before.jpg") >>> img_rgb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB) >>> for i,img in enumerate(divideInto3forTweet(img_rgb), start=1): ... img.save(f"cli.tweetile-after{i}.jpg", quality=95) +--------------------------------------------+--------------------------------------------+--------------------------------------------+ | Example | +============================================+============================================+============================================+ | Before | After | +--------------------------------------------+--------------------------------------------+--------------------------------------------+ | .. image:: _images/cli.tweetile-before.jpg | .. image:: _images/cli.tweetile-after1.jpg | .. image:: _images/cli.tweetile-after2.jpg | + + +--------------------------------------------+ | | | .. image:: _images/cli.tweetile-after3.jpg | +--------------------------------------------+--------------------------------------------+--------------------------------------------+ """ h,w,ch = img_arr.shape if ((h!=636) or (w!=1132)): warnings.warn(f"Resize the input image from {toGREEN((h,w,ch))} to {toGREEN((636,1132,ch))}.") img_arr = cv2.resize(img_arr, dsize=(1132,636)) images = [img_arr[:,:564], img_arr[:316,568:], img_arr[320:,568:]] return tuple(Image.fromarray(np.uint8(img)) for img in images)