File size: 5,167 Bytes
0e2c31f a4b6d66 3eb4bfd a4b6d66 65fb503 a4b6d66 3eb4bfd a4b6d66 b0f4df1 65fb503 a4b6d66 3eb4bfd a4b6d66 af3a707 3eb4bfd af3a707 3eb4bfd 0e2c31f 3eb4bfd 0e2c31f 3eb4bfd af3a707 3eb4bfd 0e2c31f 3eb4bfd 0e2c31f 3eb4bfd 0e2c31f 3eb4bfd a4b6d66 3eb4bfd a4b6d66 65fb503 a4b6d66 65fb503 3eb4bfd b0f4df1 3eb4bfd |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
import cv2
import numpy as np
from reportlab.pdfgen import canvas
from reportlab.lib.units import inch
from PIL import Image, ImageDraw, ImageFont
import tempfile
PAGE_WIDTH = 8.67 * inch
PAGE_HEIGHT = 11.5 * inch
MARGIN = 0.5 * inch
def verificar_contraste(imagem_array):
gray = cv2.cvtColor(imagem_array, cv2.COLOR_BGR2GRAY)
contrast = gray.std()
return "⚠️ Baixo contraste detectado!" if contrast < 30 else "✅ Contraste adequado."
def detectar_pontos(imagem_array, idade, distancia_maxima=50):
gray = cv2.cvtColor(imagem_array, cv2.COLOR_BGR2GRAY)
_, thresh = cv2.threshold(gray, 200, 255, cv2.THRESH_BINARY_INV)
contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
if not contours:
return [], None
main_contour = max(contours, key=cv2.contourArea)
epsilon = 1.0
simplified = cv2.approxPolyDP(main_contour, epsilon, closed=False)
max_pontos = min(30 + (idade - 4) * 10, 100)
step = max(1, len(simplified) // max_pontos)
pontos = [tuple(pt[0]) for pt in simplified[::step]]
if len(pontos) > 2:
ordenados = [pontos[0]]
restantes = pontos[1:]
while restantes:
ultimo = ordenados[-1]
prox = min(restantes, key=lambda p: np.hypot(p[0]-ultimo[0], p[1]-ultimo[1]))
if np.hypot(prox[0] - ultimo[0], prox[1] - ultimo[1]) > distancia_maxima:
break
ordenados.append(prox)
restantes.remove(prox)
pontos = ordenados
return pontos, thresh
def normalizar_para_preview(pontos, largura=600, altura=800, margem=50, posicao="Centro da página"):
if not pontos:
return [], 0
x_coords, y_coords = zip(*pontos)
min_x, max_x = min(x_coords), max(x_coords)
min_y, max_y = min(y_coords), max(y_coords)
escala_x = (largura - 2 * margem) / (max_x - min_x + 1e-5)
escala_y = (altura - 2 * margem) / (max_y - min_y + 1e-5)
escala = min(escala_x, escala_y)
altura_desenho = (max_y - min_y) * escala
if posicao == "Topo da página":
offset_y = margem
elif posicao == "Base da página":
offset_y = altura - margem - altura_desenho
else:
offset_y = (altura - altura_desenho) // 2
pontos_normalizados = [(
int((x - min_x) * escala + margem),
int((y - min_y) * escala + offset_y)
) for x, y in pontos]
return pontos_normalizados, escala
def gerar_preview_com_pontos(pontos, posicao):
largura, altura = 600, 800
margem = 50
img = np.ones((altura, largura, 3), dtype=np.uint8) * 255
pontos_norm, _ = normalizar_para_preview(pontos, largura, altura, margem, posicao)
for i, (x, y) in enumerate(pontos_norm):
cv2.circle(img, (x, y), 4, (0, 0, 0), -1)
cv2.putText(img, str(i+1), (x + 6, y - 6), cv2.FONT_HERSHEY_SIMPLEX, 0.4, (0, 0, 0), 1)
path = tempfile.NamedTemporaryFile(delete=False, suffix=".png").name
cv2.imwrite(path, img)
return path, img, pontos_norm
def gerar_overlay(original, pontos_norm):
overlay = original.copy()
h, w = overlay.shape[:2]
resize = cv2.resize(overlay, (w, h))
transparente = cv2.addWeighted(resize, 0.5, np.ones_like(resize) * 255, 0.5, 0)
for i, (x, y) in enumerate(pontos_norm):
if x < w and y < h:
cv2.circle(transparente, (x, y), 4, (0, 0, 0), -1)
cv2.putText(transparente, str(i+1), (x + 6, y - 6), cv2.FONT_HERSHEY_SIMPLEX, 0.4, (0, 0, 0), 1)
path = tempfile.NamedTemporaryFile(delete=False, suffix=".png").name
cv2.imwrite(path, transparente)
return path
def gerar_pdf(pontos_norm):
pdf_path = tempfile.NamedTemporaryFile(delete=False, suffix=".pdf").name
c = canvas.Canvas(pdf_path, pagesize=(PAGE_WIDTH, PAGE_HEIGHT))
for i, (x, y) in enumerate(pontos_norm):
c.circle(x, PAGE_HEIGHT - y, 2, fill=1)
c.setFont("Helvetica", 8)
c.drawString(x + 3, PAGE_HEIGHT - y + 3, str(i + 1))
c.save()
return pdf_path
def gerar_preview_kdp():
img = Image.new("RGB", (1500, 1000), color=(250, 240, 210))
draw = ImageDraw.Draw(img)
font = ImageFont.load_default()
draw.rectangle([50, 50, 1450, 950], outline="black", width=4)
draw.text((600, 100), "Dot-to-Dot Book", fill="black", font=font)
draw.text((580, 160), "For Kids Ages 4 to 12", fill="black", font=font)
draw.ellipse((1100, 700, 1300, 900), outline="gray", width=3)
draw.text((1120, 780), "Your Art Here", fill="gray", font=font)
path = tempfile.NamedTemporaryFile(delete=False, suffix=".png").name
img.save(path)
return path
def processar_e_mostrar(imagem_array, _, idade, posicao):
pontos, _ = detectar_pontos(imagem_array, idade)
preview_path, preview_img, pontos_norm = gerar_preview_com_pontos(pontos, posicao)
overlay_path = gerar_overlay(cv2.resize(imagem_array, (600, 800)), pontos_norm)
pdf_path = gerar_pdf(pontos_norm)
png_path = tempfile.NamedTemporaryFile(delete=False, suffix=".png").name
cv2.imwrite(png_path, preview_img)
return {
"preview": preview_path,
"overlay": overlay_path,
"pdf": pdf_path,
"png": png_path
}
|