From 78fcdce32751c1554b456e3cd2035eafc5cdbcdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Gruszczy=C5=84ski?= Date: Tue, 22 Jul 2025 14:19:24 +0200 Subject: [PATCH] =?UTF-8?q?obracanie=20zdj=C4=99cia=20fix?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app.py | 55 ++++++++++++++++++++++++++----------------------------- 1 file changed, 26 insertions(+), 29 deletions(-) diff --git a/app.py b/app.py index 46b4e65..0e878ae 100644 --- a/app.py +++ b/app.py @@ -267,37 +267,30 @@ def enrich_list_data(l): def save_resized_image(file, path): try: + # Otwórz i sprawdź poprawność pliku + image = Image.open(file) + image.verify() + file.seek(0) image = Image.open(file) - image.verify() # sprawdzenie poprawności pliku - file.seek(0) # reset do początku - image = Image.open(file) # ponowne otwarcie po verify() except Exception: raise ValueError("Nieprawidłowy plik graficzny") - # Obrót na podstawie EXIF try: - exif = image._getexif() - if exif: - orientation_key = next( - k for k, v in ExifTags.TAGS.items() if v == "Orientation" - ) - orientation = exif.get(orientation_key) - if orientation == 3: - image = image.rotate(180, expand=True) - elif orientation == 6: - image = image.rotate(270, expand=True) - elif orientation == 8: - image = image.rotate(90, expand=True) + # Automatyczna rotacja według EXIF (np. zdjęcia z telefonu) + image = ImageOps.exif_transpose(image) except Exception: - pass # brak lub błędny EXIF + pass # ignorujemy, jeśli EXIF jest uszkodzony lub brak - image.thumbnail((2000, 2000)) - image = image.convert("RGB") - image.info.clear() + try: + image.thumbnail((2000, 2000)) + image = image.convert("RGB") + image.info.clear() + + new_path = path.rsplit(".", 1)[0] + ".webp" + image.save(new_path, format="WEBP", quality=100, method=0) + except Exception as e: + raise ValueError(f"Błąd podczas przetwarzania obrazu: {e}") - new_path = path.rsplit(".", 1)[0] + ".webp" - #image.save(new_path, format="WEBP", quality=85, method=6) - image.save(new_path, format="WEBP", quality=100, method=0) def redirect_with_flash( message: str, category: str = "info", endpoint: str = "main_page" @@ -344,12 +337,16 @@ def _receipt_error(message): ############# OCR ########################### + def preprocess_image_for_tesseract(image): image = ImageOps.autocontrast(image) image = image.point(lambda x: 0 if x < 150 else 255) # mocniejsza binarizacja - image = image.resize((image.width * 2, image.height * 2), Image.BICUBIC) # większe powiększenie + image = image.resize( + (image.width * 2, image.height * 2), Image.BICUBIC + ) # większe powiększenie return image + def extract_total_tesseract(image): text = pytesseract.image_to_string(image, lang="pol", config="--psm 4") lines = text.splitlines() @@ -371,7 +368,7 @@ def extract_total_tesseract(image): amount )\b """, - re.IGNORECASE | re.VERBOSE + re.IGNORECASE | re.VERBOSE, ) for idx, line in enumerate(lines): @@ -420,9 +417,7 @@ def extract_total_tesseract(image): continue preferred = [ - (val, line) - for val, line in candidates - if keyword_pattern.search(line.lower()) + (val, line) for val, line in candidates if keyword_pattern.search(line.lower()) ] if preferred: @@ -433,7 +428,9 @@ def extract_total_tesseract(image): max_val = max([val for val, _ in candidates]) return round(max_val, 2), lines - data = pytesseract.image_to_data(image, lang="pol", config="--psm 4", output_type=Output.DICT) + data = pytesseract.image_to_data( + image, lang="pol", config="--psm 4", output_type=Output.DICT + ) font_candidates = [] for i in range(len(data["text"])):