def to_code(config): from PIL import Image path = CORE.relative_config_path(config[CONF_FILE]) try: image = Image.open(path) except Exception as e: raise core.EsphomeError(u"Could not load image file {}: {}".format( path, e)) if CONF_RESIZE in config: image.thumbnail(config[CONF_RESIZE]) image = image.convert('1', dither=Image.NONE) width, height = image.size if width > 500 or height > 500: _LOGGER.warning( "The image you requested is very big. Please consider using the resize " "parameter") width8 = ((width + 7) // 8) * 8 data = [0 for _ in range(height * width8 // 8)] for y in range(height): for x in range(width): if image.getpixel((x, y)): continue pos = x + y * width8 data[pos // 8] |= 0x80 >> (pos % 8) rhs = [HexInt(x) for x in data] prog_arr = cg.progmem_array(config[CONF_RAW_DATA_ID], rhs) cg.new_Pvariable(config[CONF_ID], prog_arr, width, height)
async def to_code(config): from PIL import Image path = CORE.relative_config_path(config[CONF_FILE]) try: image = Image.open(path) except Exception as e: raise core.EsphomeError(f"Could not load image file {path}: {e}") width, height = image.size if CONF_RESIZE in config: image.thumbnail(config[CONF_RESIZE]) width, height = image.size else: if width > 500 or height > 500: _LOGGER.warning( "The image you requested is very big. Please consider using" " the resize parameter.") dither = Image.NONE if config[ CONF_DITHER] == "NONE" else Image.FLOYDSTEINBERG if config[CONF_TYPE] == "GRAYSCALE": image = image.convert("L", dither=dither) pixels = list(image.getdata()) data = [0 for _ in range(height * width)] pos = 0 for pix in pixels: data[pos] = pix pos += 1 elif config[CONF_TYPE] == "RGB24": image = image.convert("RGB") pixels = list(image.getdata()) data = [0 for _ in range(height * width * 3)] pos = 0 for pix in pixels: data[pos] = pix[0] pos += 1 data[pos] = pix[1] pos += 1 data[pos] = pix[2] pos += 1 elif config[CONF_TYPE] == "BINARY": image = image.convert("1", dither=dither) width8 = ((width + 7) // 8) * 8 data = [0 for _ in range(height * width8 // 8)] for y in range(height): for x in range(width): if image.getpixel((x, y)): continue pos = x + y * width8 data[pos // 8] |= 0x80 >> (pos % 8) rhs = [HexInt(x) for x in data] prog_arr = cg.progmem_array(config[CONF_RAW_DATA_ID], rhs) cg.new_Pvariable(config[CONF_ID], prog_arr, width, height, IMAGE_TYPE[config[CONF_TYPE]])
async def to_code(config): from PIL import ImageFont conf = config[CONF_FILE] if conf[CONF_TYPE] == TYPE_LOCAL: path = CORE.relative_config_path(conf[CONF_PATH]) elif conf[CONF_TYPE] == TYPE_GFONTS: path = _compute_gfonts_local_path(conf) try: font = ImageFont.truetype(str(path), config[CONF_SIZE]) except Exception as e: raise core.EsphomeError(f"Could not load truetype file {path}: {e}") ascent, descent = font.getmetrics() glyph_args = {} data = [] for glyph in config[CONF_GLYPHS]: mask = font.getmask(glyph, mode="1") _, (offset_x, offset_y) = font.font.getsize(glyph) width, height = mask.size width8 = ((width + 7) // 8) * 8 glyph_data = [0] * (height * width8 // 8) for y in range(height): for x in range(width): if not mask.getpixel((x, y)): continue pos = x + y * width8 glyph_data[pos // 8] |= 0x80 >> (pos % 8) glyph_args[glyph] = (len(data), offset_x, offset_y, width, height) data += glyph_data rhs = [HexInt(x) for x in data] prog_arr = cg.progmem_array(config[CONF_RAW_DATA_ID], rhs) glyph_initializer = [] for glyph in config[CONF_GLYPHS]: glyph_initializer.append( cg.StructInitializer( GlyphData, ("a_char", glyph), ( "data", cg.RawExpression( f"{str(prog_arr)} + {str(glyph_args[glyph][0])}"), ), ("offset_x", glyph_args[glyph][1]), ("offset_y", glyph_args[glyph][2]), ("width", glyph_args[glyph][3]), ("height", glyph_args[glyph][4]), )) glyphs = cg.static_const_array(config[CONF_RAW_GLYPH_ID], glyph_initializer) cg.new_Pvariable(config[CONF_ID], glyphs, len(glyph_initializer), ascent, ascent + descent)
def to_code(config): from PIL import Image path = CORE.relative_config_path(config[CONF_FILE]) try: image = Image.open(path) except Exception as e: raise core.EsphomeError(f"Could not load image file {path}: {e}") if CONF_RESIZE in config: image.thumbnail(config[CONF_RESIZE]) if config[CONF_TYPE].startswith('RGB565'): width, height = image.size image = image.convert('RGB') pixels = list(image.getdata()) data = [0 for _ in range(height * width * 2)] pos = 0 for pix in pixels: r = (pix[0] >> 3) & 0x1F g = (pix[1] >> 2) & 0x3F b = (pix[2] >> 3) & 0x1F p = (r << 11) + (g << 5) + b data[pos] = (p >> 8) & 0xFF pos += 1 data[pos] = p & 0xFF pos += 1 rhs = [HexInt(x) for x in data] prog_arr = cg.progmem_array(config[CONF_RAW_DATA_ID], rhs) cg.new_Pvariable(config[CONF_ID], prog_arr, width, height, 1) else: image = image.convert('1', dither=Image.NONE) width, height = image.size if width > 500 or height > 500: _LOGGER.warning( "The image you requested is very big. Please consider using the resize " "parameter") width8 = ((width + 7) // 8) * 8 data = [0 for _ in range(height * width8 // 8)] for y in range(height): for x in range(width): if image.getpixel((x, y)): continue pos = x + y * width8 data[pos // 8] |= 0x80 >> (pos % 8) rhs = [HexInt(x) for x in data] prog_arr = cg.progmem_array(config[CONF_RAW_DATA_ID], rhs) cg.new_Pvariable(config[CONF_ID], prog_arr, width, height)
def to_code(config): from PIL import ImageFont path = CORE.relative_path(config[CONF_FILE]) try: font = ImageFont.truetype(path, config[CONF_SIZE]) except Exception as e: raise core.EsphomeError(u"Could not load truetype file {}: {}".format( path, e)) ascent, descent = font.getmetrics() glyph_args = {} data = [] for glyph in config[CONF_GLYPHS]: mask = font.getmask(glyph, mode='1') _, (offset_x, offset_y) = font.font.getsize(glyph) width, height = mask.size width8 = ((width + 7) // 8) * 8 glyph_data = [0 for _ in range(height * width8 // 8)] # noqa: F812 for y in range(height): for x in range(width): if not mask.getpixel((x, y)): continue pos = x + y * width8 glyph_data[pos // 8] |= 0x80 >> (pos % 8) glyph_args[glyph] = (len(data), offset_x, offset_y, width, height) data += glyph_data rhs = safe_exp([HexInt(x) for x in data]) prog_arr = progmem_array(config[CONF_RAW_DATA_ID], rhs) glyphs = [] for glyph in config[CONF_GLYPHS]: glyphs.append(Glyph(glyph, prog_arr, *glyph_args[glyph])) rhs = App.make_font(glyphs, ascent, ascent + descent) Pvariable(config[CONF_ID], rhs)
async def to_code(config): from PIL import Image path = CORE.relative_config_path(config[CONF_FILE]) try: image = Image.open(path) except Exception as e: raise core.EsphomeError(f"Could not load image file {path}: {e}") width, height = image.size frames = image.n_frames if CONF_RESIZE in config: new_width_max, new_height_max = config[CONF_RESIZE] ratio = min(new_width_max / width, new_height_max / height) width, height = int(width * ratio), int(height * ratio) else: if width > 500 or height > 500: _LOGGER.warning( "The image you requested is very big. Please consider using" " the resize parameter.") if config[CONF_TYPE] == "GRAYSCALE": data = [0 for _ in range(height * width * frames)] pos = 0 for frameIndex in range(frames): image.seek(frameIndex) frame = image.convert("L", dither=Image.NONE) if CONF_RESIZE in config: frame = frame.resize([width, height]) pixels = list(frame.getdata()) if len(pixels) != height * width: raise core.EsphomeError( f"Unexpected number of pixels in {path} frame {frameIndex}: ({len(pixels)} != {height*width})" ) for pix in pixels: data[pos] = pix pos += 1 elif config[CONF_TYPE] == "RGB24": data = [0 for _ in range(height * width * 3 * frames)] pos = 0 for frameIndex in range(frames): image.seek(frameIndex) frame = image.convert("RGB") if CONF_RESIZE in config: frame = frame.resize([width, height]) pixels = list(frame.getdata()) if len(pixels) != height * width: raise core.EsphomeError( f"Unexpected number of pixels in {path} frame {frameIndex}: ({len(pixels)} != {height*width})" ) for pix in pixels: data[pos] = pix[0] pos += 1 data[pos] = pix[1] pos += 1 data[pos] = pix[2] pos += 1 elif config[CONF_TYPE] == "RGB565": data = [0 for _ in range(height * width * 2 * frames)] pos = 0 for frameIndex in range(frames): image.seek(frameIndex) frame = image.convert("RGB") if CONF_RESIZE in config: frame = frame.resize([width, height]) pixels = list(frame.getdata()) if len(pixels) != height * width: raise core.EsphomeError( f"Unexpected number of pixels in {path} frame {frameIndex}: ({len(pixels)} != {height*width})" ) for pix in pixels: R = pix[0] >> 3 G = pix[1] >> 2 B = pix[2] >> 3 rgb = (R << 11) | (G << 5) | B data[pos] = rgb >> 8 pos += 1 data[pos] = rgb & 255 pos += 1 elif config[CONF_TYPE] == "BINARY": width8 = ((width + 7) // 8) * 8 data = [0 for _ in range((height * width8 // 8) * frames)] for frameIndex in range(frames): image.seek(frameIndex) frame = image.convert("1", dither=Image.NONE) if CONF_RESIZE in config: frame = frame.resize([width, height]) for y in range(height): for x in range(width): if frame.getpixel((x, y)): continue pos = x + y * width8 + (height * width8 * frameIndex) data[pos // 8] |= 0x80 >> (pos % 8) rhs = [HexInt(x) for x in data] prog_arr = cg.progmem_array(config[CONF_RAW_DATA_ID], rhs) cg.new_Pvariable( config[CONF_ID], prog_arr, width, height, frames, espImage.IMAGE_TYPE[config[CONF_TYPE]], )
def to_code(config): from PIL import Image path = CORE.relative_config_path(config[CONF_FILE]) try: image = Image.open(path) except Exception as e: raise core.EsphomeError(f"Could not load image file {path}: {e}") width, height = image.size frames = image.n_frames if CONF_RESIZE in config: image.thumbnail(config[CONF_RESIZE]) width, height = image.size else: if width > 500 or height > 500: _LOGGER.warning( "The image you requested is very big. Please consider using" " the resize parameter.") if config[CONF_TYPE] == 'GRAYSCALE': data = [0 for _ in range(height * width * frames)] pos = 0 for frameIndex in range(frames): image.seek(frameIndex) frame = image.convert('L', dither=Image.NONE) pixels = list(frame.getdata()) for pix in pixels: data[pos] = pix pos += 1 elif config[CONF_TYPE] == 'RGB24': data = [0 for _ in range(height * width * 3 * frames)] pos = 0 for frameIndex in range(frames): image.seek(frameIndex) frame = image.convert('RGB') pixels = list(frame.getdata()) for pix in pixels: data[pos] = pix[0] pos += 1 data[pos] = pix[1] pos += 1 data[pos] = pix[2] pos += 1 elif config[CONF_TYPE] == 'BINARY': width8 = ((width + 7) // 8) * 8 data = [0 for _ in range((height * width8 // 8) * frames)] for frameIndex in range(frames): image.seek(frameIndex) frame = image.convert('1', dither=Image.NONE) for y in range(height): for x in range(width): if frame.getpixel((x, y)): continue pos = x + y * width8 + (height * width8 * frameIndex) data[pos // 8] |= 0x80 >> (pos % 8) rhs = [HexInt(x) for x in data] prog_arr = cg.progmem_array(config[CONF_RAW_DATA_ID], rhs) cg.new_Pvariable(config[CONF_ID], prog_arr, width, height, frames, espImage.IMAGE_TYPE[config[CONF_TYPE]])