From 7d3eba20294b55d2f7da51a9bf71766b75df5b4e Mon Sep 17 00:00:00 2001 From: Rodrigo Martins Date: Wed, 1 Jan 2025 22:44:05 -0300 Subject: [PATCH] Estiliza pagina de upload externo - responsiva (novo47) --- document_detector.py | 97 ++++++++++++++++++++++++++++++++++++++++++++ document_history.php | 85 ++++++++++++++++++++++++++++++++++++++ menu.php | 2 +- style.css | 47 +++++++++++++++++++++ upload.php | 64 +++++++++++++++++++++++++++++ 5 files changed, 294 insertions(+), 1 deletion(-) create mode 100644 document_detector.py create mode 100644 document_history.php create mode 100644 upload.php diff --git a/document_detector.py b/document_detector.py new file mode 100644 index 0000000..7190eaf --- /dev/null +++ b/document_detector.py @@ -0,0 +1,97 @@ +import cv2 +import numpy as np +import sys +import json +from pathlib import Path + +def order_points(pts): + rect = np.zeros((4, 2), dtype="float32") + s = pts.sum(axis=1) + rect[0] = pts[np.argmin(s)] + rect[2] = pts[np.argmax(s)] + diff = np.diff(pts, axis=1) + rect[1] = pts[np.argmin(diff)] + rect[3] = pts[np.argmax(diff)] + return rect + +def process_document(image_path, output_path): + try: + # Carrega e verifica a imagem + image = cv2.imread(str(image_path)) + if image is None: + raise Exception("Não foi possível carregar a imagem") + + original = image.copy() + + # Pré-processamento + gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) + blurred = cv2.GaussianBlur(gray, (5, 5), 0) + edges = cv2.Canny(blurred, 50, 150) + + # Encontra contornos + contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) + if not contours: + raise Exception("Nenhum contorno encontrado") + + # Ordena contornos por área + contours = sorted(contours, key=cv2.contourArea, reverse=True) + doc_corners = None + + # Procura o documento + for contour in contours: + peri = cv2.arcLength(contour, True) + approx = cv2.approxPolyDP(contour, 0.02 * peri, True) + if len(approx) == 4: + doc_corners = approx + break + + if doc_corners is None: + raise Exception("Documento não encontrado") + + # Processa cantos e aplica transformação + doc_corners = doc_corners.reshape(4, 2) + ordered_corners = order_points(doc_corners) + + (tl, tr, br, bl) = ordered_corners + widthA = np.linalg.norm(br - bl) + widthB = np.linalg.norm(tr - tl) + maxWidth = max(int(widthA), int(widthB)) + + heightA = np.linalg.norm(tr - br) + heightB = np.linalg.norm(tl - bl) + maxHeight = max(int(heightA), int(heightB)) + + dst = np.array([ + [0, 0], + [maxWidth - 1, 0], + [maxWidth - 1, maxHeight - 1], + [0, maxHeight - 1] + ], dtype="float32") + + # Aplica transformação perspectiva + matrix = cv2.getPerspectiveTransform(ordered_corners, dst) + warped = cv2.warpPerspective(original, matrix, (maxWidth, maxHeight)) + + # Salva resultado + cv2.imwrite(str(output_path), warped) + + return { + "success": True, + "message": "Processamento concluído com sucesso", + "width": maxWidth, + "height": maxHeight + } + + except Exception as e: + return { + "success": False, + "message": str(e) + } + +if __name__ == "__main__": + if len(sys.argv) != 3: + print(json.dumps({"success": False, "message": "Argumentos inválidos"})) + sys.exit(1) + + result = process_document(Path(sys.argv[1]), Path(sys.argv[2])) + print(json.dumps(result)) diff --git a/document_history.php b/document_history.php new file mode 100644 index 0000000..5681ca4 --- /dev/null +++ b/document_history.php @@ -0,0 +1,85 @@ +connect_error) { + die("Connection failed: " . $mysqli->connect_error); +} + +// Buscar histórico de documentos processados +$query = "SELECT pd.*, u.username FROM processed_documents pd + LEFT JOIN users u ON pd.user_id = u.id + ORDER BY pd.created_at DESC"; +$result = $mysqli->query($query); +?> + +
+

Histórico de Documentos Processados

+ + + + + + + + + + + + + fetch_assoc()): ?> + + + + + + + + + +
Data/HoraUsuárioDocumento OriginalDocumento ProcessadoAções
+ + Ver Original + + + + Ver Processado + + + +
+
+ + diff --git a/menu.php b/menu.php index afd199e..3b39a3a 100644 --- a/menu.php +++ b/menu.php @@ -12,7 +12,7 @@ if (!isset($_SESSION['user_id'])) {
  • Autenticador de Provas Digitais diff --git a/style.css b/style.css index 4eb5acf..2723ee2 100644 --- a/style.css +++ b/style.css @@ -209,3 +209,50 @@ textarea { #search-button:hover { background-color: #0056b3; } + +/* Estilos para processamento de documentos */ +.upload-form { + max-width: 600px; + margin: 20px auto; + padding: 20px; + background: #f5f5f5; + border-radius: 5px; +} + +.result-preview { + margin-top: 30px; +} + +.image-comparison { + display: flex; + justify-content: space-around; + margin-top: 20px; + flex-wrap: wrap; +} + +.image-comparison img { + max-width: 45%; + height: auto; + margin: 10px; + border: 1px solid #ddd; + box-shadow: 0 0 5px rgba(0,0,0,0.2); +} + +.alert { + padding: 15px; + margin-bottom: 20px; + border: 1px solid transparent; + border-radius: 4px; +} + +.alert-success { + color: #155724; + background-color: #d4edda; + border-color: #c3e6cb; +} + +.alert-error { + color: #721c24; + background-color: #f8d7da; + border-color: #f5c6cb; +} diff --git a/upload.php b/upload.php new file mode 100644 index 0000000..c320ed6 --- /dev/null +++ b/upload.php @@ -0,0 +1,64 @@ + + + + + Processador de Documentos + + + +
    + + +
    + +
    +

    Resultado do Processamento:

    +
    +

    Documento Original:

    + Original +
    +
    +

    Documento Processado:

    + Processado +
    +
    + +
    + + + +