Add Python reference implementation
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
parent
b5f2518eeb
commit
a6e08ba9a1
@ -0,0 +1,67 @@
|
|||||||
|
from PIL import Image
|
||||||
|
from pathlib import Path
|
||||||
|
from io import BytesIO
|
||||||
|
from collections import namedtuple
|
||||||
|
from enum import Enum
|
||||||
|
import requests
|
||||||
|
|
||||||
|
Dimensions = namedtuple('Dimensions', ['width', 'height'])
|
||||||
|
|
||||||
|
|
||||||
|
def import_from_path(path: Path) -> Image:
|
||||||
|
return Image.open(path)
|
||||||
|
|
||||||
|
|
||||||
|
def import_from_url(url: str) -> Image:
|
||||||
|
r = requests.get(url)
|
||||||
|
return Image.open(BytesIO(r.content))
|
||||||
|
|
||||||
|
|
||||||
|
def convert_to_black_white(im: Image) -> Image:
|
||||||
|
return im.convert('1')
|
||||||
|
|
||||||
|
|
||||||
|
def convert_to_grayscale(im: Image) -> Image:
|
||||||
|
return im.convert('L')
|
||||||
|
|
||||||
|
|
||||||
|
def resize(im: Image, size: Dimensions) -> Image:
|
||||||
|
return im.resize(size)
|
||||||
|
|
||||||
|
|
||||||
|
def align_horizontal(images: list[Image]) -> Image:
|
||||||
|
largeur_totale = sum(im.width for im in images)
|
||||||
|
hauteur_max = max(images, key=lambda im: im.height).height
|
||||||
|
dst = Image.new(images[0].mode, (largeur_totale, hauteur_max))
|
||||||
|
|
||||||
|
largeur = 0
|
||||||
|
for img in images:
|
||||||
|
dst.paste(img, (largeur, 0))
|
||||||
|
largeur += img.width
|
||||||
|
return dst
|
||||||
|
|
||||||
|
|
||||||
|
def align_vertical(images: list[Image]) -> Image:
|
||||||
|
hauteur_totale = sum(im.height for im in images)
|
||||||
|
largeur_max = max(images, key=lambda im: im.width).width
|
||||||
|
dst = Image.new(images[0].mode, (largeur_max, hauteur_totale))
|
||||||
|
|
||||||
|
hauteur = 0
|
||||||
|
for img in images:
|
||||||
|
dst.paste(img, (0, hauteur))
|
||||||
|
hauteur += img.height
|
||||||
|
return dst
|
||||||
|
|
||||||
|
|
||||||
|
def fusion_image(im1: Image, im2: Image, opacity: float = 0.5) -> Image:
|
||||||
|
assert im1.mode == im2.mode, f'Image mode must be the same {im1.mode} != {im2.mode}'
|
||||||
|
return Image.blend(im1, im2, opacity)
|
||||||
|
|
||||||
|
|
||||||
|
def create_gif(images: list[Image], duration: int = 40):
|
||||||
|
images[0].save('animated.gif', save_all=True, append_images=images[1:], duration=duration, loop=0)
|
||||||
|
return import_from_path(Path('animated.gif'))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
import_from_url('https://codefirst.iut.uca.fr/git/assets/img/avatar_default.png')
|
Loading…
Reference in new issue