def _make_color(struct: Struct) -> Color: channels = (struct.r, struct.g, struct.b) if None in channels: return Color() return Color.from_rgb(*channels)
def _define_color(color: Any) -> Color: if _iterable(color): return Color.from_rgb(*color) if isinstance(color, Color): return Color(color.value) return Color(color)
def from_data(cls, data: ExtDict, author: Union[ExtDict, AbstractUser], client: Client) -> Comment: if isinstance(author, ExtDict): if any(key.isdigit() for key in author.keys()): author = AbstractUser.from_data(author, client=client) else: author = AbstractUser(**author, client=client) color_string = data.get(Index.COMMENT_COLOR, "255,255,255") color = Color.from_rgb(*map(int, color_string.split(","))) return cls( body=Coder.do_base64(data.get(Index.COMMENT_BODY, ""), encode=False, errors="replace"), rating=data.getcast(Index.COMMENT_RATING, 0, int), timestamp=data.get(Index.COMMENT_TIMESTAMP, "unknown"), id=data.getcast(Index.COMMENT_ID, 0, int), is_spam=bool(data.getcast(Index.COMMENT_IS_SPAM, 0, int)), type=CommentType.from_value( data.getcast(Index.COMMENT_TYPE, 0, int), 0), color=color, level_id=data.getcast(Index.COMMENT_LEVEL_ID, 0, int), level_percentage=data.getcast(Index.COMMENT_LEVEL_PERCENTAGE, -1, int), author=author, client=client, )
def from_data(cls, data: ExtDict, client: Client) -> MapPack: try: level_ids = tuple(map(int, data.get(Index.MAP_PACK_LEVEL_IDS, "").split(","))) except ValueError: level_ids = () color_string = data.get(Index.MAP_PACK_COLOR, "255,255,255") color = Color.from_rgb(*map(int, color_string.split(","))) difficulty = Converter.value_to_pack_difficulty( data.getcast(Index.MAP_PACK_DIFFICULTY, 0, int) ) return cls( id=data.getcast(Index.MAP_PACK_ID, 0, int), name=data.get(Index.MAP_PACK_NAME, "unknown"), level_ids=level_ids, stars=data.getcast(Index.MAP_PACK_STARS, 0, int), coins=data.getcast(Index.MAP_PACK_COINS, 0, int), difficulty=difficulty, color=color, client=client, )
def color(self) -> Color: """:class:`.Color`: Color of a map pack.""" return self.options.get("color", Color(0xFFFFFF))
def color(self) -> Color: """:class:`.Color`: Color of the comment. Oftenly equals ``gd.Color(0xffffff)``.""" return self.options.get("color", Color(0xFFFFFF))
def get_glow_color(color_1: Color, color_2: Color) -> Color: if not color_1.value: # black return Color(0xFFFFFF) # white return color_2
def generate( self, icon_type: Union[int, str, IconType] = IconType.CUBE, icon_id: int = 1, color_1: Color = COLOR_1, color_2: Color = COLOR_2, glow_outline: bool = False, error_on_not_found: bool = False, ) -> ImageType: if not self.is_loaded(): self.load() result = Image.new("RGBA", (250, 250), ALPHA) icon = Icon(type=icon_type, id=icon_id) start = icon.get_start() sprites = [ self.get_sheet(name).get_sprite(name) for name in self.cache if name.startswith(start) ] if not sprites: # sprites not found, fall back to ID=1 if error_on_not_found: raise LookupError(f"{icon} does not exist.") return self.generate( icon_type=icon_type, icon_id=1, color_1=color_1, color_2=color_2, glow_outline=glow_outline, ) if not glow_outline: sprites = [sprite for sprite in sprites if GLOW not in sprite.name] self.reorder_sprites(sprites, icon) for sprite in sprites: name = sprite.name copy_level = sprite.copy_level x, y = sprite.rectangle.x, sprite.rectangle.y width, height = sprite.size.width, sprite.size.height center_x, center_y = width // 2, height // 2 off_x, off_y = sprite.offset.x, sprite.offset.y real_width, real_height = sprite.rectangle.width, sprite.rectangle.height is_rotated = sprite.rotated if is_rotated: real_width, real_height = real_height, real_width image = sprite.sheet.image.crop( (x, y, x + real_width, y + real_height)) if is_rotated: image = image.rotate(90, resample=Image.BICUBIC, expand=True) if copy_level and GLOW not in name: image = reduce_brightness(image) image, off_x, off_y = self.get_image_and_offset( name, icon_id, image, off_x, off_y, copy_level) if GLOW in name: image = apply_color(image, get_glow_color(color_1, color_2).to_rgb()) elif TWO in name: image = apply_color(image, color_2.to_rgb()) elif EXTRA not in name and THREE not in name: image = apply_color(image, color_1.to_rgb()) draw_x = 100 - center_x + off_x draw_y = 100 - center_y - off_y draw_off_x, draw_off_y = { IconType.ROBOT: (0, -20), IconType.SPIDER: (6, -5), IconType.UFO: (0, 30), }.get(icon.type, (0, 0)) result.alpha_composite( image, (25 + draw_off_x + draw_x, 25 + draw_off_y + draw_y)) return result
from gd.typing import Any, Dict, Iterator, List, Sequence, Tuple, Union, ref from gd.utils.enums import IconType from gd.utils.text_tools import JSDict log = get_logger(__name__) try: from PIL import Image, ImageOps from PIL.Image import Image as ImageType except ImportError: ImageType = ref("PIL.Image.Image") log.warning( "Failed to load Pillow/PIL. Icon Factory will not be supported.") ALPHA = (0, 0, 0, 0) COLOR_1 = Color(0x00FF00) COLOR_2 = Color(0x00FFFF) DARK = Color(0x808080) ASSETS = Path(__file__).parent / "assets" ROB_NAMES = { IconType.CUBE: "player", IconType.SHIP: "ship", IconType.BALL: "player_ball", IconType.UFO: "bird", IconType.WAVE: "dart", IconType.ROBOT: "robot", IconType.SPIDER: "spider", } ROB_SPRITE_STARTS = tuple(name + "_" for name in ROB_NAMES.values())
def color_2(self) -> Color: """:class:`.Color`: A second color of the iconset.""" return self.options.get("color_2", Color(0x00FFFF))
def color_1(self) -> Color: """:class:`.Color`: A first color of the iconset.""" return self.options.get("color_1", Color(0x00FF00))