Source code for pyvisor.icon

# -*- coding: utf-8 -*-
"""
Created on Thu Jun 16 13:19:47 2016

@author: bgeurten
"""


from PIL import Image, ImageDraw
import pygame
import numpy as np
from pathlib import Path

from .paths import ensure_tmp_icon_dir
from .resources import icons_root


[docs] class Icon: """Recolourable icon for behaviour display in the scorer window. Loads a decal image, tints it to the behaviour's assigned colour, and converts it to a pygame surface for blitting. """ def __init__(self, size=(96, 96), color=(144, 21, 222), alpha=255): self.size = size self.image = [] self.color = color self.alpha = alpha self.circle = [] self.decall = [] self.radius = int(self.size[0]/2) self.icon = None
[docs] def readImage(self, filename): self.decall = Image.open(filename).convert('RGBA')
[docs] def decall2icon(self): self.drawCircle() pos = self.getDecallPos() size = self.getMaxDecallSize() self.decall = self.decall.resize(size, Image.LANCZOS) self.circle.paste(self.decall, pos, self.decall) self.icon = self.circle
[docs] def drawCircle(self): im = Image.new('RGBA', self.size) draw = ImageDraw.Draw(im) draw.ellipse((0, 0, im.size[0], im.size[1]), fill=self.color) del draw self.circle = im
[docs] def getMaxDecallSize(self): # the diagonal of the biggest square in a circle is the diameter of that circle # D denotes the diameter and Pythogoras c² = a²+b² becomes c²=2*a² for a = b ( # as for squares a=b) => (2r)² = 2a² | (2r)² = a² | 4r²/2 =a² |sqrt(2r²) =a decallSize = int(np.sqrt(2*self.radius**2)) return (decallSize,decallSize)
[docs] def getDecallPos(self): X = (np.sin(np.pi/4) * -1*self.radius) + self.size[0]/2 Y = (np.cos(np.pi/4) * -1*self.radius) + self.size[0]/2 return (int(X),int(Y))
[docs] def invertDecall(self): r, g, b, a = self.decall.split() def invert(image): return image.point(lambda p: 255 - p) r, g, b = map(invert, (r, g, b)) self.decall = Image.merge(self.decall.mode, (r, g, b, a))
[docs] def icon2pygame(self) -> pygame.image: raw_str = self.icon.tobytes("raw", 'RGBA') return pygame.image.frombytes(raw_str, self.size , 'RGBA')
[docs] def write_tmp_icon(path_to_icon, color): if not path_to_icon: return None icon_path = Path(path_to_icon) try: relative_path = icon_path.relative_to(icons_root()) except ValueError: folders = [] fname = icon_path.stem extension = icon_path.suffix else: folders = list(relative_path.parent.parts) fname = relative_path.stem extension = relative_path.suffix color_str = "_%i_%i_%i" % color tmp_parts = folders + [fname + color_str + extension] relative_tmp_path = Path(*tmp_parts) tmp_icon_dir = ensure_tmp_icon_dir() target_path = tmp_icon_dir / relative_tmp_path if target_path.is_file(): return target_path target_path.parent.mkdir(parents=True, exist_ok=True) I = Icon(color=color) I.readImage(str(icon_path)) I.decall2icon() with target_path.open('wb') as f: I.icon.save(f) return target_path