habulaj commited on
Commit
29d6503
·
verified ·
1 Parent(s): fbc5caf

Update routers/image.py

Browse files
Files changed (1) hide show
  1. routers/image.py +60 -10
routers/image.py CHANGED
@@ -427,9 +427,9 @@ def calculate_text_height(text: str, font, max_width: int) -> int:
427
 
428
  return total_height
429
 
430
- def render_slide_text(draw: ImageDraw.Draw, text: str, x: int, y: int, max_width: int, max_lines: int = 5, center_vertical: bool = False) -> None:
431
  """
432
- Renderiza texto para slides com fonte padrão, cor #000000, tamanho inicial 32px.
433
  Suporta formatação com asteriscos para negrito.
434
 
435
  Args:
@@ -440,6 +440,7 @@ def render_slide_text(draw: ImageDraw.Draw, text: str, x: int, y: int, max_width
440
  max_width: Largura máxima do texto
441
  max_lines: Número máximo de linhas (padrão: 5)
442
  center_vertical: Se True, centraliza verticalmente o texto na posição Y
 
443
  """
444
  import re
445
 
@@ -642,7 +643,7 @@ def render_slide_text(draw: ImageDraw.Draw, text: str, x: int, y: int, max_width
642
  current_x = x
643
  for i, (segment_text, segment_font) in enumerate(line):
644
  font_to_use = final_regular_font if segment_font == regular_font else final_bold_font
645
- draw.text((current_x, current_y), segment_text, fill=(0, 0, 0, 255), font=font_to_use) # Cor #000000
646
  bbox = font_to_use.getbbox(segment_text)
647
  current_x += bbox[2] - bbox[0]
648
 
@@ -657,19 +658,64 @@ def render_slide_text(draw: ImageDraw.Draw, text: str, x: int, y: int, max_width
657
  # Aplicar line height de 120% (adicionar 20% de espaçamento extra)
658
  current_y += int(max_line_height * 1.20)
659
 
660
- def create_slide_canvas(image_url: str, slide: int, text: Optional[str] = None) -> BytesIO:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
661
  """
662
  Cria um canvas para slides com imagem cortada baseada no parâmetro slide.
663
 
664
  Args:
665
  image_url: URL da imagem de fundo
666
  slide: 1 para cortar início (880px), 2 para cortar final (400px)
 
 
667
  """
668
  # Dimensões do poster
669
  canvas_width, canvas_height = 1080, 1350
670
 
671
- # Criar canvas com fundo #70b4a7
672
- canvas = Image.new("RGBA", (canvas_width, canvas_height), color=(112, 180, 167, 255)) # #70b4a7
 
 
 
673
 
674
  # Baixar imagem original
675
  img = download_image_from_url(image_url)
@@ -743,11 +789,14 @@ def create_slide_canvas(image_url: str, slide: int, text: Optional[str] = None)
743
  # Colar imagem no canvas
744
  canvas.paste(img_with_mask, (x_pos, y_pos), img_with_mask)
745
 
 
 
 
746
  # Adicionar texto se slide for 1 e text for fornecido
747
  if slide == 1 and text and text.strip():
748
  draw = ImageDraw.Draw(canvas)
749
  # Renderizar texto com as especificações: X: 200, Y: 210, L: 815, MAX 5 linhas
750
- render_slide_text(draw, text, x=200, y=210, max_width=815, max_lines=5)
751
 
752
  # Adicionar texto se slide for 2 e text for fornecido
753
  if slide == 2 and text and text.strip():
@@ -755,7 +804,7 @@ def create_slide_canvas(image_url: str, slide: int, text: Optional[str] = None)
755
  # Renderizar texto com as especificações: X: 445, Y: 430, L: 585, A: 748, MAX 19 linhas
756
  # A imagem do slide 2 vai de Y: 425 a Y: 1205 (altura 780px)
757
  # Para centralizar o texto na área da imagem, o centro é Y: 425 + (780/2) = 815
758
- render_slide_text(draw, text, x=445, y=815, max_width=585, max_lines=19, center_vertical=True)
759
 
760
  buffer = BytesIO()
761
  canvas.convert("RGB").save(buffer, format="PNG")
@@ -887,12 +936,13 @@ def get_image(
887
  citation: Optional[str] = Query(None, description="Citação a ser exibida entre aspas (fonte Cheltenham Normal 700)"),
888
  text_position: str = Query("bottom", description="Posição do texto: 'top' ou 'bottom'"),
889
  citation_position: str = Query("top", description="Posição da citação: 'top' ou 'bottom'"),
890
- slide: Optional[int] = Query(None, description="Número do slide: 1 para início (880px), 2 para final (400px)")
 
891
  ):
892
  try:
893
  # Se o parâmetro slide for fornecido, usar a funcionalidade de slides
894
  if slide is not None:
895
- buffer = create_slide_canvas(image_url, slide, text)
896
  else:
897
  # Usar funcionalidade normal de criação de imagem
898
  buffer = create_canvas(image_url, text, citation, text_position, citation_position)
 
427
 
428
  return total_height
429
 
430
+ def render_slide_text(draw: ImageDraw.Draw, text: str, x: int, y: int, max_width: int, max_lines: int = 5, center_vertical: bool = False, text_color: tuple = (0, 0, 0, 255)) -> None:
431
  """
432
+ Renderiza texto para slides com fonte padrão, tamanho inicial 32px.
433
  Suporta formatação com asteriscos para negrito.
434
 
435
  Args:
 
440
  max_width: Largura máxima do texto
441
  max_lines: Número máximo de linhas (padrão: 5)
442
  center_vertical: Se True, centraliza verticalmente o texto na posição Y
443
+ text_color: Cor do texto como tuple (R, G, B, A)
444
  """
445
  import re
446
 
 
643
  current_x = x
644
  for i, (segment_text, segment_font) in enumerate(line):
645
  font_to_use = final_regular_font if segment_font == regular_font else final_bold_font
646
+ draw.text((current_x, current_y), segment_text, fill=text_color, font=font_to_use)
647
  bbox = font_to_use.getbbox(segment_text)
648
  current_x += bbox[2] - bbox[0]
649
 
 
658
  # Aplicar line height de 120% (adicionar 20% de espaçamento extra)
659
  current_y += int(max_line_height * 1.20)
660
 
661
+ def get_slide_color(slide_color: int) -> tuple:
662
+ """
663
+ Retorna a cor do slide baseada no número fornecido.
664
+
665
+ Args:
666
+ slide_color: Número da cor (1-8)
667
+
668
+ Returns:
669
+ Tuple (R, G, B, A) da cor
670
+ """
671
+ color_map = {
672
+ 1: (0, 0, 0, 255), # #000000 - Preto
673
+ 2: (191, 198, 147, 255), # #BFC693
674
+ 3: (246, 164, 29, 255), # #f6a41d
675
+ 4: (245, 244, 239, 255), # #f5f4ef
676
+ 5: (111, 180, 165, 255), # #6fb4a5
677
+ 6: (25, 83, 208, 255), # #1953d0
678
+ 7: (255, 80, 17, 255), # #ff5011
679
+ 8: (255, 217, 194, 255), # #ffd9c2
680
+ }
681
+
682
+ # Se o número for inválido, usar preto como padrão
683
+ return color_map.get(slide_color, (0, 0, 0, 255))
684
+
685
+ def get_text_color(slide_color: int) -> tuple:
686
+ """
687
+ Retorna a cor do texto baseada na cor do slide.
688
+
689
+ Args:
690
+ slide_color: Número da cor do slide (1-8)
691
+
692
+ Returns:
693
+ Tuple (R, G, B, A) da cor do texto
694
+ """
695
+ # Se for cor 1 (preto), usar texto branco, senão usar texto preto
696
+ if slide_color == 1:
697
+ return (255, 255, 255, 255) # Branco
698
+ else:
699
+ return (0, 0, 0, 255) # Preto
700
+
701
+ def create_slide_canvas(image_url: str, slide: int, text: Optional[str] = None, slide_color: int = 1) -> BytesIO:
702
  """
703
  Cria um canvas para slides com imagem cortada baseada no parâmetro slide.
704
 
705
  Args:
706
  image_url: URL da imagem de fundo
707
  slide: 1 para cortar início (880px), 2 para cortar final (400px)
708
+ text: Texto opcional para exibir no slide
709
+ slide_color: Cor do slide (1-8)
710
  """
711
  # Dimensões do poster
712
  canvas_width, canvas_height = 1080, 1350
713
 
714
+ # Obter cor do slide
715
+ slide_bg_color = get_slide_color(slide_color)
716
+
717
+ # Criar canvas com cor do slide
718
+ canvas = Image.new("RGBA", (canvas_width, canvas_height), color=slide_bg_color)
719
 
720
  # Baixar imagem original
721
  img = download_image_from_url(image_url)
 
789
  # Colar imagem no canvas
790
  canvas.paste(img_with_mask, (x_pos, y_pos), img_with_mask)
791
 
792
+ # Obter cor do texto baseada na cor do slide
793
+ text_color = get_text_color(slide_color)
794
+
795
  # Adicionar texto se slide for 1 e text for fornecido
796
  if slide == 1 and text and text.strip():
797
  draw = ImageDraw.Draw(canvas)
798
  # Renderizar texto com as especificações: X: 200, Y: 210, L: 815, MAX 5 linhas
799
+ render_slide_text(draw, text, x=200, y=210, max_width=815, max_lines=5, text_color=text_color)
800
 
801
  # Adicionar texto se slide for 2 e text for fornecido
802
  if slide == 2 and text and text.strip():
 
804
  # Renderizar texto com as especificações: X: 445, Y: 430, L: 585, A: 748, MAX 19 linhas
805
  # A imagem do slide 2 vai de Y: 425 a Y: 1205 (altura 780px)
806
  # Para centralizar o texto na área da imagem, o centro é Y: 425 + (780/2) = 815
807
+ render_slide_text(draw, text, x=445, y=815, max_width=585, max_lines=19, center_vertical=True, text_color=text_color)
808
 
809
  buffer = BytesIO()
810
  canvas.convert("RGB").save(buffer, format="PNG")
 
936
  citation: Optional[str] = Query(None, description="Citação a ser exibida entre aspas (fonte Cheltenham Normal 700)"),
937
  text_position: str = Query("bottom", description="Posição do texto: 'top' ou 'bottom'"),
938
  citation_position: str = Query("top", description="Posição da citação: 'top' ou 'bottom'"),
939
+ slide: Optional[int] = Query(None, description="Número do slide: 1 para início (880px), 2 para final (400px)"),
940
+ slide_color: Optional[int] = Query(1, description="Cor do slide: 1=#000000, 2=#BFC693, 3=#f6a41d, 4=#f5f4ef, 5=#6fb4a5, 6=#1953d0, 7=#ff5011, 8=#ffd9c2")
941
  ):
942
  try:
943
  # Se o parâmetro slide for fornecido, usar a funcionalidade de slides
944
  if slide is not None:
945
+ buffer = create_slide_canvas(image_url, slide, text, slide_color)
946
  else:
947
  # Usar funcionalidade normal de criação de imagem
948
  buffer = create_canvas(image_url, text, citation, text_position, citation_position)