1
0
Fork 0
paraderos_led/notebooks/example_notebook.ipynb

914 lines
73 KiB
Plaintext
Raw Normal View History

2023-08-29 00:18:41 -04:00
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import requests\n",
"from io import BytesIO\n",
"\n",
"def load_image_from_url(url=None):\n",
" if(url is None):\n",
" # URL de la imagen en línea\n",
" url = \"https://img.freepik.com/iconos-gratis/autobus_318-574563.jpg\"\n",
"\n",
" # Descarga la imagen desde la URL\n",
" response = requests.get(url)\n",
" image_data = response.content\n",
" # Crea un objeto Image desde los datos descargados\n",
" image = Image.open(BytesIO(image_data))\n",
" return image\n",
"\n",
"def crop_image(image):\n",
" # Corta 150 píxeles de la parte superior e inferior\n",
" top_cut = 165\n",
" bottom_cut = 165\n",
" width, height = image.size\n",
" cropped_image = image.crop((0, top_cut, width, height - bottom_cut))\n",
" return cropped_image\n",
"\n",
"def resize_image(image, target_width=None, target_height=None):\n",
" \"\"\"\n",
" Ajusta el tamaño de la imagen mientras mantiene las proporciones.\n",
" \n",
" Args:\n",
" image (PIL.Image.Image): La imagen a redimensionar.\n",
" target_width (int, opcional): El ancho objetivo deseado.\n",
" target_height (int, opcional): La altura objetivo deseada.\n",
" \n",
" Returns:\n",
" PIL.Image.Image: La imagen redimensionada.\n",
" \"\"\"\n",
" width, height = image.size\n",
" aspect_ratio = width / height\n",
" \n",
" if target_width is None and target_height is None:\n",
" raise ValueError(\"Debes proporcionar al menos una de las dimensiones objetivo.\")\n",
" \n",
" if target_width is not None and target_height is None:\n",
" new_width = target_width\n",
" new_height = int(target_width / aspect_ratio)\n",
" elif target_width is None and target_height is not None:\n",
" new_width = int(target_height * aspect_ratio)\n",
" new_height = target_height\n",
" else:\n",
" new_width = target_width\n",
" new_height = target_height\n",
" \n",
" resized_image = image.resize((new_width, new_height))\n",
" return resized_image\n",
"\n",
"def load_draw_image():\n",
" image = load_image_from_url()\n",
" image = crop_image(image)\n",
" image = resize_image(image, target_height=25)\n",
" return image"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"from PIL import ImageDraw, ImageFont\n",
"\n",
"def draw_rounded_rectangle_with_text(draw, position, width, height, text, font=None, fontsize=16, border_color=(0, 0, 0), background_color=(255, 255, 255), text_color=(0, 0, 0)):\n",
" \"\"\"\n",
" Dibuja un rectángulo con bordes redondeados y un texto encima en un objeto ImageDraw.\n",
"\n",
" Args:\n",
" draw (PIL.ImageDraw.ImageDraw): El objeto ImageDraw en el que se dibujará.\n",
" position (tuple): Las coordenadas (x, y) de la esquina superior izquierda del rectángulo.\n",
" width (int): El ancho del rectángulo.\n",
" height (int): La altura del rectángulo.\n",
" text (str): El texto a dibujar encima del rectángulo.\n",
" font (PIL.ImageFont.ImageFont, opcional): La fuente a utilizar para el texto.\n",
" border_color (tuple, opcional): El color del borde del rectángulo en formato RGB.\n",
" background_color (tuple, opcional): El color de fondo del rectángulo en formato RGB.\n",
" text_color (tuple, opcional): El color del texto en formato RGB.\n",
" \"\"\"\n",
" corner_radius = 10\n",
" border_width = 2\n",
" \n",
" x, y = position\n",
" x2, y2 = x + width, y + height\n",
" \n",
" draw.rounded_rectangle(\n",
" [(x + border_width, y + border_width), (x2 - border_width, y2 - border_width)],\n",
" corner_radius,\n",
" outline=border_color,\n",
" width=border_width,\n",
" fill=background_color\n",
" )\n",
" \n",
" text_position = ((x + x2) // 2, (y + y2) // 2)\n",
" \n",
" if font is None:\n",
" font = ImageFont.load_default()\n",
" \n",
" # text_size = font.getsize()\n",
" # text_size = draw.textsize(text, font)\n",
"\n",
" txt_img = Image.new(\"RGBA\", (width, height), (255,255,255,0))\n",
" # font = ImageFont.truetype(font, fontsize)\n",
" d = ImageDraw.Draw(txt_img)\n",
" text_size = d.textsize(text, font=font)\n",
"\n",
" text_position = (text_position[0] - text_size[0] // 2, text_position[1] - text_size[1] // 2)\n",
" \n",
" draw.text(text_position, text, fill=text_color, font=font)\n"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"from PIL import Image, ImageDraw, ImageFont\n",
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
"\n",
"# Crear una imagen en blanco con el tamaño especificado\n",
"width, height = 160, 80\n",
"background_color = (0, 0, 128) # Azul marino\n",
"border_color = (0, 0, 0) # Negro\n",
"text_color = (255, 255, 255) # Blanco\n",
"corner_radius = 5\n",
"\n",
"image = Image.new(\"RGB\", (width, height), text_color)\n",
"draw = ImageDraw.Draw(image)\n",
"\n",
"# Definir la información\n",
"linea_bus = \"16 I\"\n",
"\n",
"def load_barlow(font_size=12):\n",
" # Ruta a la fuente TTF personalizada\n",
" font_path = \"/app/data/Barlow-Medium.ttf\"\n",
" # Carga la fuente\n",
" return ImageFont.truetype(font_path, font_size)\n",
"\n",
"font = load_barlow()\n",
"# font = ImageFont.load_default()\n",
"\n",
"# Dibujar el recuadro con esquinas redondeadas\n",
"border_width = 1\n",
"rect_width = 30\n",
"rect_width -= border_width\n",
"rect_height = 30\n",
"rect_height -= border_width\n",
"\n",
"draw.rounded_rectangle(\n",
" [(border_width, border_width), (rect_width - border_width, rect_height - border_width)],\n",
" corner_radius,\n",
" outline=border_color,\n",
" width=border_width,\n",
" fill=background_color\n",
")\n",
"w, h = draw.im.size\n",
"# Dibujar la placa patente en el centro\n",
"text_width, text_height = draw.im.size\n",
"# .textsize(linea_bus, font=font)\n",
"text_position = (0.15*rect_width, 0.2*rect_height)\n",
"\n",
"draw.text(text_position, linea_bus, fill=text_color, font=font)\n",
"\n",
"# Poner el tiempo estimado de espera\n",
"text_position = (0.5*rect_width, 0.25*rect_height)\n",
"draw.text(text_position, linea_bus, fill=text_color, font=font)\n",
"\n",
"# # Llamar a la función para dibujar un rectángulo con texto encima\n",
"# draw_rounded_rectangle_with_text(draw, (50, 50), 300, 100, \"Texto de Prueba\")\n",
"\n",
"# Supongamos que tienes una función llamada load_draw_image() que devuelve la imagen que quieres agregar\n",
"loaded_image = load_draw_image()\n",
"\n",
"# Crear una imagen en blanco del mismo tamaño que loaded_image con fondo blanco\n",
"white_background = Image.new(\"RGB\", loaded_image.size, (255, 255, 255))\n",
"\n",
"# Pega la loaded_image en la imagen en blanco\n",
"white_background.paste(loaded_image, (0, 0), loaded_image)\n",
"\n",
"# Calcula la posición para agregar la imagen cargada\n",
"image_position = (0, 50) # Cambia esto según tu diseño\n",
"\n",
"# Agrega la imagen a la imagen creada\n",
"image.paste(white_background, image_position)\n",
"\n",
"# Convertir la imagen de PIL a un array de numpy para matplotlib\n",
"image_array = np.array(image)\n",
"\n",
"# Mostrar la imagen utilizando matplotlib\n",
"plt.imshow(image_array)\n",
"plt.axis(\"off\") # Ocultar ejes\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"from PIL import Image, ImageDraw\n",
"\n",
"def cartel_micro(h, w):\n",
" image = Image.new(\"RGB\", (w, h), \"white\")\n",
" proportion = 0.4\n",
" width_border = 1\n",
" draw = ImageDraw.Draw(image)\n",
"\n",
" # Draw a rounded rectangle\n",
" draw.rounded_rectangle((0, 0, w-width_border, h-width_border), fill=\"blue\", outline=\"black\",\n",
" width=width_border, radius=5)\n",
" draw.rounded_rectangle((0, 0, proportion*w-width_border, h-width_border), fill=\"yellow\", outline=\"black\",\n",
" width=width_border, radius=5)\n",
" return image\n",
" \n",
" \n",
"if __name__ == \"__main__\":\n",
" plt.imshow(cartel_micro(30, 60))"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"(0, 6, 18, 20)\n",
"17.5\n"
]
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"def load_barlow(font_size=12):\n",
" # Ruta a la fuente TTF personalizada\n",
" font_path = \"/app/data/Barlow-Medium.ttf\"\n",
" # Carga la fuente\n",
" return ImageFont.truetype(font_path, font_size)\n",
"\n",
"def number_letter_bus(h, w):\n",
" image = Image.new(\"RGB\", (w, h), \"white\")\n",
" linea_bus = \"16\"\n",
" text_color = 'black'\n",
" font = load_barlow(font_size=20)\n",
" font_width = font.getlength(linea_bus)\n",
" print(font.getbbox(linea_bus))\n",
" print(font_width)\n",
" font_width = np.round(font_width)\n",
" offset_width = np.round(w/2)\n",
" #- np.round(font_width/2)\n",
" text_position = (offset_width, 0)\n",
"\n",
" draw = ImageDraw.Draw(image)\n",
" draw.text(\n",
" #text_position,\n",
" (0,0),\n",
" linea_bus,\n",
" fill=text_color,\n",
" font=font,\n",
" align =\"center\"\n",
" )\n",
" return image\n",
"\n",
"if __name__ == \"__main__\":\n",
" plt.imshow(number_letter_bus(30, 60))"
]
},
{
"cell_type": "code",
"execution_count": 39,
"metadata": {},
"outputs": [],
"source": [
"class MyDraw():\n",
" def __init__(self, height, width):\n",
" self.height = height\n",
" self.width = width\n",
" pass\n",
"\n",
" def save_image(self, filename):\n",
" self.image.save(filename)\n",
" pass\n",
"\n",
" def start_draw(self, background_color=None):\n",
" if background_color is None:\n",
" background_color = self.theme_params['background_color']\n",
"\n",
" self.image = Image.new(\"RGB\", (self.width, self.height), background_color)\n",
" self.draw = ImageDraw.Draw(self.image)\n",
" pass\n",
"\n",
" def add_image(self, obj, position):\n",
" image_to_add = obj.get_image() # Obtiene la imagen del objeto pasado como argumento\n",
" if image_to_add:\n",
" self.image.paste(image_to_add, position)\n",
" pass\n",
"\n",
" def get_draw(self):\n",
" return self.draw\n",
" \n",
" def get_image(self):\n",
" return self.image\n",
"\n",
" def set_params(self,params):\n",
" self.prms = params\n",
" pass\n",
"\n",
" def set_theme(self,mode='day'):\n",
" if(mode=='day'):\n",
" self.start_day_mode()\n",
" else:\n",
" self.start_night_mode()\n",
" pass\n",
"\n",
" def start_day_mode(self):\n",
" self.theme_params = {\n",
" 'background_color': 'white',\n",
" 'text_color': 'black',\n",
" 'poster_line_color': 'black',\n",
" }\n",
" pass\n",
"\n",
" def start_night_mode(self):\n",
" self.theme_params = {\n",
" 'background_color': 'black',\n",
" 'text_color': 'white',\n",
" 'poster_line_color': 'gray',\n",
" }\n",
" pass\n",
" \n",
" def load_barlow(self, font_size=None):\n",
" # Ruta a la fuente TTF personalizada\n",
" font_path = \"/app/data/Barlow-Medium.ttf\"\n",
" # Carga la fuente\n",
" if font_size is None:\n",
" self.font = ImageFont.truetype(font_path, self.prms['font_size'])\n",
" else:\n",
" self.font = ImageFont.truetype(font_path, font_size)\n",
" pass\n",
"\n",
" def preview(self):\n",
" plt.imshow(self.image)\n",
" plt.axis('off')\n",
" plt.show()\n",
"\n",
" def crop_image(self, top_cut, bottom_cut):\n",
" width, height = self.image.size\n",
" self.image = self.image.crop((0, top_cut, width, height - bottom_cut))\n",
" pass\n",
"\n",
" def resize_image(self, target_width=None, target_height=None):\n",
" \"\"\"\n",
" Ajusta el tamaño de la imagen mientras mantiene las proporciones.\n",
" \n",
" Args:\n",
" image (PIL.Image.Image): La imagen a redimensionar.\n",
" target_width (int, opcional): El ancho objetivo deseado.\n",
" target_height (int, opcional): La altura objetivo deseada.\n",
" \n",
" Returns:\n",
" PIL.Image.Image: La imagen redimensionada.\n",
" \"\"\"\n",
" width, height = self.image.size\n",
" aspect_ratio = width / height\n",
" \n",
" if target_width is None and target_height is None:\n",
" raise ValueError(\"Debes proporcionar al menos una de las dimensiones objetivo.\")\n",
" \n",
" if target_width is not None and target_height is None:\n",
" new_width = target_width\n",
" new_height = int(target_width / aspect_ratio)\n",
" elif target_width is None and target_height is not None:\n",
" new_width = int(target_height * aspect_ratio)\n",
" new_height = target_height\n",
" else:\n",
" new_width = target_width\n",
" new_height = target_height\n",
" \n",
" self.image = self.image.resize((new_width, new_height))\n",
" pass\n",
" \n",
"class BusPoster(MyDraw):\n",
"\n",
" def start_draw(self):\n",
" return super().start_draw()\n",
"\n",
" def set_colors(self):\n",
" width_border = self.prms['width_border']\n",
" proportion = self.prms['proportion']\n",
" fill_color_l = self.prms['letter_background_color']\n",
" fill_color_n = self.prms['number_background_color']\n",
"\n",
"\n",
" self.draw.rounded_rectangle(\n",
" (0, 0, self.width-width_border, self.height-width_border),\n",
" fill=fill_color_l,\n",
" outline=self.theme_params['poster_line_color'],\n",
" width=width_border,\n",
" radius=5)\n",
" \n",
" self.draw.rounded_rectangle(\n",
" (0, 0, proportion*self.width-width_border, self.height-width_border),\n",
" fill=fill_color_n,\n",
" outline=self.theme_params['poster_line_color'],\n",
" width=width_border,\n",
" radius=5)\n",
" pass\n",
"\n",
" def set_bus_number(self, bus_number=\"11\"):\n",
" text_color = 'black'\n",
" width_border = self.prms['width_border']\n",
" text_bbox = self.font.getbbox(str(bus_number))\n",
" font_width, font_height = text_bbox[2] - text_bbox[0], text_bbox[3] - text_bbox[1]\n",
" offset_width = np.round((self.prms['proportion']*self.width-width_border)/2) - np.round(font_width/2)\n",
" text_position = (offset_width,0)\n",
" self.draw.text(\n",
" text_position,\n",
" bus_number,\n",
" fill=text_color,\n",
" font=self.font,\n",
" # align =\"center\"\n",
" )\n",
" pass\n",
"\n",
" def set_bus_letter(self, bus_letter=\"E\"):\n",
" proportion = self.prms['proportion']\n",
" width_border = self.prms['width_border']\n",
" text_color = 'white'\n",
" text_bbox = self.font.getbbox(str(bus_letter))\n",
" font_width, font_height = text_bbox[2] - text_bbox[0], text_bbox[3] - text_bbox[1]\n",
" offset_width = np.round((proportion*self.width-width_border)) + 0.75*np.round(font_width/2)\n",
" text_position = (offset_width,0)\n",
" self.draw.text(\n",
" text_position,\n",
" bus_letter,\n",
" fill=text_color,\n",
" font=self.font,\n",
" # align =\"center\"\n",
" )\n",
" pass\n",
"\n",
"\n",
"def bus_number_letter_image():\n",
" cartel = BusPoster(30, 60)\n",
" # cartel.start_day_mode()\n",
" cartel.start_night_mode()\n",
" cartel.start_draw()\n",
"\n",
" params = {\n",
" 'proportion': 0.6,\n",
" 'width_border': 1,\n",
" 'font_size': 25,\n",
" 'number_background_color': 'yellow',\n",
" 'letter_background_color': 'blue',\n",
" }\n",
"\n",
" cartel.set_params(params)\n",
" cartel.load_barlow()\n",
" cartel.set_colors()\n",
" cartel.set_bus_number()\n",
" cartel.set_bus_letter()\n",
" return cartel.get_image()"
]
},
{
"cell_type": "code",
"execution_count": 40,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<matplotlib.image.AxesImage at 0x7f3db75d3760>"
]
},
"execution_count": 40,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"bus_poster = bus_number_letter_image()\n",
"plt.imshow(bus_poster)"
]
},
{
"cell_type": "code",
"execution_count": 41,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAgMAAAFKCAYAAACAZFxuAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8pXeV/AAAACXBIWXMAAA9hAAAPYQGoP6dpAAAPE0lEQVR4nO3dW6hV1d8G4Lk9ZOesFENMpCK0QsISKiKi6CI7gRUkHaEItczM1DKQzuciwTJMJQqJ0gtLBcvoYB7T7IAkmZimJFZQYBa51fW/+S6+7+M3dK/+a7X39vc8l+/cc47hWmO7XyZzrNVSq9VqFQCQVpf2ngAA0L6UAQBIThkAgOSUAQBIThkAgOSUAQBIThkAgOSUAQBIThkAgOS6tfUHW1pamjkPAKAJ2vJBw+4MAEByygAAJKcMAEByygAAJKcMAEByygAAJKcMAEByygAAJKcMAEByygAAJKcMAEByygAAJKcMAEByygAAJKcMAEByygAAJKcMAEByygAAJKcMAEByygAAJKcMAEByygAAJKcMAEByygAAJKcMAEByygAAJKcMAEByygAAJKcMAEByygAAJKcMAEByygAAJKcMAEByygAAJKcMAEByygAAJKcMAEByygAAJKcMAEByygAAJKcMAEByygAAJKcMAEByygAAJKcMAEByygAAJKcMAEByygAAJKcMAEBy3dp7As3w7LPPFo+NHj06zLt37x7mXbrEfenvv/8O859++qk49rBhw8L87bffDvPzzjsvzFtbW4tjAEC93BkAgOSUAQBIThkAgOSUAQBIThkAgORaarVarU0/2NLS7Lm0q7vvvjvMS0/033TTTc2cDgA0RFv+zLszAADJKQMAkJwyAADJKQMAkJwyAADJHZLfTdBRnXLKKWG+bNmyMO/bt29d1x8/fnzx2AMPPBDmpV0ir7zySpgvXrw4zOfNm1cce/v27WFeej1efPHFun5++PDhxbFXr14d5tdcc02YDxgwIMxXrVoV5hs2bCiOfdZZZ4X57Nmzw3zcuHHFa9Vr5MiRYT5lypQwL303xzPPPBPmzz///D+bWODwww8P8xkzZoT51VdfXbzWzp07w/y+++4L80WLFoX56aefHualdVBV5bXQqHVwwQUXFMcufb/Jtm3biufUM0ZpPVVV89fUxIkTi2MPGTIkzG+44YYwv+iii8J8zpw5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
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"class TimeAnnouncement(MyDraw):\n",
"\n",
" def start_draw(self):\n",
" super().start_draw()\n",
" self.border = 1\n",
"\n",
" def set_background(self):\n",
" self.draw.rounded_rectangle(\n",
" (0, 0, self.width-0.5*self.border, self.height-0.5*self.border),\n",
" fill=\"#dcdcdc\",\n",
" outline=\"gray\",\n",
" width=self.border,\n",
" radius=1)\n",
" pass\n",
"\n",
" def set_base_text(self):\n",
" text = \"Tiempo aprox\"\n",
" text_color = self.theme_params['text_color']\n",
" self.load_barlow(font_size=11)\n",
" text_bbox = self.font.getbbox(text)\n",
" font_width, font_height = text_bbox[2] - text_bbox[0], text_bbox[3] - text_bbox[1]\n",
" # print(font_width, font_height)\n",
" offset_width = (np.round((self.width-self.border)) - np.round(font_width))/2\n",
" text_position = (offset_width,5)\n",
" # text_position = (0, 0)\n",
" self.draw.text(\n",
" text_position,\n",
" text,\n",
" fill=text_color,\n",
" font=self.font,\n",
" align =\"center\"\n",
" )\n",
" pass\n",
"\n",
" def set_min_max_text(self, min_time, max_time):\n",
"\n",
" text = \"Tiempo aprox\"\n",
" text_color = self.theme_params['text_color']\n",
" self.load_barlow(font_size=11)\n",
" text_bbox = self.font.getbbox(text)\n",
" base_font_width, base_font_height = text_bbox[2] - text_bbox[0], text_bbox[3] - text_bbox[1]\n",
"\n",
" if (int(max_time) <= 1):\n",
" text = f\"< 1 min\"\n",
" else:\n",
" text = f'{min_time} a {max_time} min'\n",
" \n",
" self.load_barlow(font_size=18)\n",
" text_bbox = self.font.getbbox(text)\n",
" font_width, font_height = text_bbox[2] - text_bbox[0], text_bbox[3] - text_bbox[1]\n",
" # print(font_width, font_height)\n",
" offset_width = (np.round((self.width-self.border)) - np.round(font_width))/2\n",
" offset_height = (np.round((self.height-self.border)) - np.round(base_font_height))/2\n",
" text_position = (offset_width,5+offset_height)\n",
" # text_position = (0, 0)\n",
" self.draw.text(\n",
" text_position,\n",
" text,\n",
" fill=text_color,\n",
" font=self.font,\n",
" align =\"center\"\n",
" )\n",
"\n",
"time_anmc = TimeAnnouncement(50, 80)\n",
"time_anmc.start_night_mode()\n",
"time_anmc.start_draw()\n",
"# time_anmc.set_background()\n",
"time_anmc.set_base_text()\n",
"time_anmc.set_min_max_text(min_time=0, max_time=1)\n",
"time_anmc.preview()"
]
},
{
"cell_type": "code",
"execution_count": 42,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAgMAAAFKCAYAAACAZFxuAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8pXeV/AAAACXBIWXMAAA9hAAAPYQGoP6dpAAAMgUlEQVR4nO3dT4hV9f/H8Rm1tEyywDAxEwnJhYugIChokBbRPwp0U/lnV2IlCQXmQpGCwhAjgpBok1FhRZDCtAkjk/64MFMyELJEKou00ApHne/it/vx/kxza64z+no8lq873nP0DvnsMMfTOzg4ONgDAMQaN9onAACMLjEAAOHEAACEEwMAEE4MAEA4MQAA4cQAAIQTAwAQTgwAQLgJw/3C3t7ebp4HANAFw/mHhl0ZAIBwYgAAwokBAAgnBgAgnBgAgHBiAADCiQEACCcGACCcGACAcGIAAMKJAQAIJwYAIJwYAIBwYgAAwokBAAgnBgAgnBgAgHBiAADCiQEACCcGACCcGACAcGIAAMKJAQAIJwYAIJwYAIBwYgAAwokBAAgnBgAgnBgAgHBiAADCiQEACCcGACCcGACAcGIAAMKJAQAIJwYAIJwYAIBwYgAAwokBAAgnBgAgnBgAgHBiAADCiQEACCcGACCcGACAcGIAAMKJAQAIJwYAIJwYAIBwE0b7BDg3rrrqqnL/+eefy/3kyZPlPjg4WO4//vhj89hPPvlkue/fv7/c33777XK/+eaby31gYKB57NH0yCOPlPt7771X7kePHu3m6TBKrrvuunK/UL7PuTC4MgAA4cQAAIQTAwAQTgwAQDgxAADhegdbPx7+/7+wt7fb50IXTZ8+vdwPHjxY7pdddllH79/X19d8bdu2bR2d04kTJzo69li1b9++cn/ooYfKfc+ePV08GyDVcP6ad2UAAMKJAQAIJwYAIJwYAIBwYgAAwnk2ASNix44dzdeOHz9e7nPmzCn3/v7+cp8xY0a5T5kypXnsN998s9xvu+22cv/+++/L/eGHHy73xYsXN489b968ct+1a1e5P/fcc+W+fv36cp80aVLz2Js3by73e++9t9xbz6hYtWpVuR87dqx57K1bt5b7kSNHyn3u3Lnl/vLLL5f7mjVrmsduWblyZbmvXr263MeNq/8/aePGjc1jtD6/1vf5zp07y731fT6an/f27dubx+bC4MoAAIQTAwAQTgwAQDgxAADhxAAAhHM3AV13+vTpcm/9xHZrb7n//vubr7WeqTFt2rRyX7BgQbm37iZYsmRJ89i33npruY/Uswladyv09PT0nDlzptxnzZpV7jNnziz3Tz/9tNzvueee5rGvuOKKcm/dwdH6d9O//vrrcm/95HxPT0/PpZdeWu5r164t9xtuuKHcT506Ve5ffvll89gfffRRuf/222/l3un3+Wh+3ldeeWXz2MN8vA1jnCsDABBODABAODEAAOHEAACEEwMAEM7dBJz3Pv/88+Zr69atK/cNGzaU+1tvvVXuQ901MFoOHjzYfK3109+HDx8u9/Hjx5f75MmTOz6v7777rtyHOt9O3mf69OnNX3PttdeW+2effVburWdRtMyfP7/52u+//17urWcTdGo0P++JEyc2j/333383X+P84coAAIQTAwAQTgwAQDgxAADhxAAAhBMDABDOrYV03YQJ9bfZ2bNnR+T9v/322+ZrrQfRLFy4sNw3btxY7rt27Sr3J5544h/OrnuWL1/efO2iiy4q9xkzZpR767P4888/Oz6vkXpwTet9Wg+f6unp6bn44otH5Ngtx44d6+r7D2Wsft5cGFwZAIBwYgAAwokBAAgnBgAgnBgAgHDuJmBE9PX1NV+bOnVquY/UTy4vW7as+dqCBQvKvfWT2X/88Ue5tx54NJSBgYFynz17drnv2bOno/efMmVK87Vff/21o3NavHhxR8ceq3bv3l3uL730Urm3HmzUupNhx44dzWPfd9995T5S3+c+b7rJlQEACCcGACCcGACAcGIAAMKJAQAI526CEK1/i3zy5MnlfuLEiXJv/ZT1Tz/91Dz2gw8+2NE5dfrMgvfff7/52t13313uR44cKffjx4+X+8qVKzs6p56enp433nij3Lds2VLua9asKfcXX3yx3F999dXmsVt/Jr/88ku59/f3l3vr8x7qMxqpZ078m++PAwcOlHvrbpAvvvii3MePH1/umzZtah5779695T5nzpxy7/TPaTQ/75F63gRjlysDABBODABAODEAAOHEAACEEwMAEK53cJg/Jtrb29vtcwEARthw/pp3ZQAAwokBAAgnBgAgnBgAgHBiAADCiQEACCcGACCcGACAcGIAAMKJAQAIJwYAIJwYAIBwYgAAwokBAAgnBgAgnBgAgHBiAADCiQEACCcGACCcGACAcGIAAMKJAQAIJwYAIJwYAIBwYgAAwokBAAgnBgAgnBgAgHBiAADCiQEACCcGACCcGACAcGIAAMKJAQAIJwYAIJwYAIBwYgAAwokBAAgnBgAgnBgAgHBiAADCiQEACCcGACCcGACAcGIAAMKJAQAIJwYAIJwYAIBwYgAAwokBAAgnBgAgnBgAgHBiAADCiQEACCcGACCcGACAcGIAAMKJAQAIJwYAIJwYAIBwYgAAwokBAAgnBgAgnBgAgHBiAADCiQEACCcGACCcGACAcGIAAMKJAQAIJwYAIJwYAIBwYgAAwokBAAgnBgAgnBgAgHBiAADCiQEACCcGACCcGACAcGIAAMKJAQAIJwYAIJwYAIBwYgAAwokBAAgnBgAgnBgAgHBiAADCiQEACCcGACCcGACAcGIAAMKJAQAIJwYAIJwYAIBwYgAAwokBAAg3YbRPgFzz5s0r93Xr1pX7woULy/3w4cPNY8yePbvT0+q6/v7+cu/r6yv3SZMmdfFsAFwZAIB4YgAAwokBAAgnBgAgnBgAgHBiAADCubWQrrv88svLfd++feV+5syZjvYJE86vb+PW+Z5vvw/gwuHKAACEEwMAEE4MAEA4MQAA4cQAAITz48t03YkTJ8p96dKl5b5t27Zy37lzZ7lPnTr1X50XAP/HlQEACCcGACCcGACAcGIAAMKJAQAI524Cuq71TIEtW7ac4zPJcfXVV5f7J598Uu6tOzJuvPHGcj906FDz2P39/eXe19dX7itWrCj3p556qtxnzZrVPPY333xT7itXriz3kydPlvumTZvK/aabbmoe++jRo+W+efPmcn/22Web7wXnmisDABBODABAODEAAOHEAACEEwMAEM7dBHCeGuqZDB9++GG5X3PNNeV+++23l/tQdw20TJhQ/2dl4sSJ5b5+/fpyf+2118p95syZzWMvWbKk3D/44INyP3XqVLlv37693D/++OPmsZctW1buzzzzTLn/8MMP5f766683jwHd4soAAIQTAwAQTgwAQDgxAADhxAAAhHM3AYxxl1xySblv27at+Wvmz59f7osXLy731jMLzoW77rqr3Pfs2dPxe/3111/lvnz58nLfsGFDubeeizCUrVu3lvtXX31V7nfeeWe5u5uA0eDKAACEEwMAEE4MAEA4MQAA4cQAAIQTAwAQzq2FMEb09vaW+zvvvFPut9xyS8fH2L9/f8e/ZqScPXu23P/NLYQtu3fv7urXD2Xv3r3lPjAwUO7Tpk0bsWPDf+XKAACEEwMAEE4MAEA4MQAA4cQAAIRzNwGMEePG1W1+xx13lPuKFSua7/X888+X+9NPP13uixYt+oez++8GBwe7fozWHQsj9fX/xrk4BvxXrgwAQDgxAADhxAAAhBMDABBODABAOHcTwBjXumvglVdeaf6auXPnlvtjjz1W7tdff325Hzhw4B/ODrgQuDIAAOHEAACEEwMAEE4MAEA4MQAA4dxNAGPEmTNnyn2ouwZaNm3aVO6PPvpoua9evbrcly5d2vGxgfOPKwMAEE4MAEA4MQAA4cQAAIQTAwAQzt0EcAE6dOhQub/77rvl/sADD5T72rVrO3p/4PzkygAAhBMDABBODABAODEAAOHEAACEEwMAEM6thZw3Tp8+3dE+Vo3m7+OFF14o90WLFpX7qlWryv3
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"class DistanceAnnouncement(MyDraw):\n",
"\n",
" def start_draw(self):\n",
" super().start_draw()\n",
" self.border = 1\n",
"\n",
" def set_background(self):\n",
" self.draw.rounded_rectangle(\n",
" (0, 0, self.width-0.5*self.border, self.height-0.5*self.border),\n",
" fill=\"#dcdcdc\",\n",
" outline=\"gray\",\n",
" width=self.border,\n",
" radius=1)\n",
" pass\n",
"\n",
" def set_base_text(self):\n",
" text = \"Distancia\"\n",
" text_color = self.theme_params['text_color']\n",
" self.load_barlow(font_size=11)\n",
" text_bbox = self.font.getbbox(text)\n",
" font_width, font_height = text_bbox[2] - text_bbox[0], text_bbox[3] - text_bbox[1]\n",
" # print(font_width, font_height)\n",
" offset_width = (np.round((self.width-self.border)) - np.round(font_width))/2\n",
" text_position = (offset_width,5)\n",
" # text_position = (0, 0)\n",
" self.draw.text(\n",
" text_position,\n",
" text,\n",
" fill=text_color,\n",
" font=self.font,\n",
" align =\"center\"\n",
" )\n",
" pass\n",
"\n",
" def set_distance_text(self, distance):\n",
"\n",
" text = \"Distancia\"\n",
" text_color = self.theme_params['text_color']\n",
" self.load_barlow(font_size=11)\n",
" text_bbox = self.font.getbbox(text)\n",
" base_font_width, base_font_height = text_bbox[2] - text_bbox[0], text_bbox[3] - text_bbox[1]\n",
"\n",
"\n",
" text = f'{distance} km'\n",
" self.load_barlow(font_size=18)\n",
" text_bbox = self.font.getbbox(text)\n",
" font_width, font_height = text_bbox[2] - text_bbox[0], text_bbox[3] - text_bbox[1]\n",
" # print(font_width, font_height)\n",
" offset_width = (np.round((self.width-self.border)) - np.round(font_width))/2\n",
" offset_height = (np.round((self.height-self.border)) - np.round(base_font_height))/2\n",
" text_position = (offset_width,5+offset_height)\n",
" # text_position = (0, 0)\n",
" self.draw.text(\n",
" text_position,\n",
" text,\n",
" fill=text_color,\n",
" font=self.font,\n",
" align =\"center\"\n",
" )\n",
"\n",
"dist_anmc = DistanceAnnouncement(50, 80)\n",
"dist_anmc.start_night_mode()\n",
"dist_anmc.start_draw()\n",
"dist_anmc.border = 0\n",
"# dist_anmc.set_background()\n",
"dist_anmc.set_base_text()\n",
"dist_anmc.set_distance_text(distance=1)\n",
"dist_anmc.preview()"
]
},
{
"cell_type": "code",
"execution_count": 43,
"metadata": {},
"outputs": [],
"source": [
"import requests\n",
"import io\n",
"class BusPlate():\n",
" def __init__(self, url=None) -> None:\n",
" if url is None:\n",
" self.url = \"https://matriculasdelmundo.com/gRCH1.php\"\n",
" pass\n",
"\n",
" def set_url(self, url):\n",
" self.url = url\n",
" pass\n",
"\n",
" def get_image(self):\n",
" if hasattr(self, 'image'):\n",
" return self.image\n",
" else:\n",
" print(\"Error: No se ha generado ninguna imagen aún.\")\n",
" return None\n",
"\n",
" def request_bus_plate(self, bus_plate=None):\n",
" if bus_plate is None:\n",
" self.bus_plate = \"AABB11\"\n",
" else:\n",
" self.bus_plate = bus_plate\n",
"\n",
" params = {\n",
" \"textRCH1\": self.bus_plate[0:2],\n",
" \"textRCH1A\": self.bus_plate[2:4],\n",
" \"textRCH1B\": self.bus_plate[4:],\n",
" \"textRCH1C\": \"\"\n",
" }\n",
"\n",
" self.response = requests.get(self.url, params=params)\n",
" pass\n",
"\n",
" def save_bus_plate_image(self):\n",
" if self.response.status_code == 200:\n",
" filename = f\"/app/data/output/plate_{self.bus_plate}.png\" \n",
" with open(filename, \"wb\") as f:\n",
" f.write(self.response.content)\n",
" print(f\"Imagen generada guardada como '{filename}'\")\n",
" else:\n",
" print(\"Error al guardar la imagen generada\")\n",
" pass\n",
"\n",
" def generate_image(self):\n",
" image_bytes = io.BytesIO(self.response.content)\n",
" self.image = Image.open(image_bytes)\n",
" self.image = self.image.convert(\"RGBA\") # Convertir a formato RGBA\n",
" pass\n",
"\n",
" def resize_image(self, new_size):\n",
" proportion = np.min([self.image.size[0]/new_size[0], self.image.size[1]/new_size[1]])\n",
" nx, ny = int(np.round(image.size[0]/proportion)), int(np.round(image.size[1]/proportion))\n",
" self.image = self.image.resize((nx, ny))\n",
" pass\n",
"\n",
" def preview(self):\n",
" plt.imshow(self.image)\n",
" plt.axis('off')\n",
" plt.show()\n",
" pass"
]
},
{
"cell_type": "code",
"execution_count": 44,
"metadata": {},
"outputs": [],
"source": [
"class BusImage(MyDraw):\n",
" def __init__(self):\n",
" pass\n",
" \n",
" def load_image_from_url(self, url=None):\n",
" if(url is None):\n",
" # URL de la imagen en línea\n",
" url = \"https://img.freepik.com/iconos-gratis/autobus_318-574563.jpg\"\n",
"\n",
" # Descarga la imagen desde la URL\n",
" response = requests.get(url)\n",
" image_data = response.content\n",
" # Crea un objeto Image desde los datos descargados\n",
" self.image = Image.open(BytesIO(image_data))\n",
" # Crear una imagen en blanco del mismo tamaño que loaded_image con fondo blanco\n",
" background = Image.new(\"RGB\", self.image.size, self.theme_params['background_color'])\n",
"\n",
" # Pega la loaded_image en la imagen en blanco\n",
" background.paste(self.image, (0, 0), self.image)\n",
" \n",
" self.image = background\n",
"\n",
" # Calcula la posición para agregar la imagen cargada\n",
" image_position = (0, 0) # Cambia esto según tu diseño\n",
"\n",
" # Agrega la imagen a la imagen creada\n",
" self.image.paste(background, image_position)\n",
" pass"
]
},
{
"cell_type": "code",
"execution_count": 45,
"metadata": {},
"outputs": [],
"source": [
"theme = 'night'\n",
"\n",
"panel_height, panel_width = 40, 80\n",
"n_panels = 3\n",
"full_panel = MyDraw(n_panels*panel_height, n_panels*panel_width)\n",
"full_panel.set_theme(theme)\n",
"full_panel.start_draw()\n",
"# full_panel.preview()\n",
"\n",
"bp = BusPlate()\n",
"plate = \"WXYZ88\"\n",
"bp.request_bus_plate(bus_plate=plate)\n",
"bp.generate_image()\n",
"bp.resize_image((40,80))\n",
"\n",
"dist_anmc = DistanceAnnouncement(50, 80)\n",
"dist_anmc.set_theme(theme)\n",
"dist_anmc.start_draw()\n",
"# dist_anmc.set_background()\n",
"dist_anmc.set_base_text()\n",
"dist_anmc.set_distance_text(distance=5)\n",
"\n",
"time_anmc = TimeAnnouncement(50, 80)\n",
"time_anmc.set_theme(theme)\n",
"time_anmc.start_draw()\n",
"# time_anmc.set_background()\n",
"time_anmc.set_base_text()\n",
"time_anmc.set_min_max_text(min_time=2, max_time=3)\n",
"\n",
"poster = BusPoster(30, 60)\n",
"poster.set_theme(theme)\n",
"poster.start_draw()\n",
"\n",
"poster_params = {\n",
" 'proportion': 0.6,\n",
" 'width_border': 1,\n",
" 'font_size': 25,\n",
" 'number_background_color': 'yellow',\n",
" 'letter_background_color': 'green',\n",
"}\n",
"\n",
"poster.set_params(poster_params)\n",
"poster.load_barlow()\n",
"poster.set_colors()\n",
"poster.set_bus_number(bus_number=\"20\")\n",
"poster.set_bus_letter(bus_letter=\"L\")\n",
"\n",
"bm = BusImage()\n",
"bm.set_theme(theme)\n",
"bm.load_image_from_url()\n",
"bm.crop_image(top_cut=165, bottom_cut=165)\n",
"bm.resize_image(target_width=80)\n",
"\n",
"full_panel.add_image(bp, (120, 80))\n",
"full_panel.add_image(dist_anmc, (90, 10))\n",
"full_panel.add_image(time_anmc, (160, 10))\n",
"full_panel.add_image(poster, (40, 80))\n",
"full_panel.add_image(bm, (5,20))\n",
"full_panel.get_image()\n",
"full_panel.save_image('/app/data/output.png')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"orig_nbformat": 4
},
"nbformat": 4,
"nbformat_minor": 2
}