diff --git a/batch_extractor.py b/batch_extractor.py new file mode 100644 index 0000000..cb7c6d5 --- /dev/null +++ b/batch_extractor.py @@ -0,0 +1,78 @@ +import os +import zipfile +import tempfile +import pandas as pd +from read_image import read_datamatrix_zxing, extract_barcodes_from_pdf +import click +import render_eps + +def extract_eps_from_zip(zip_path: str) -> list: + """ + Распаковывает zip-архив, ищет eps-файлы, + прогоняет их через read_datamatrix_zxing. + Возвращает список кортежей (текст, base64). + """ + results = [] + + # Используем временную директорию для безопасного извлечения файлов + with tempfile.TemporaryDirectory() as tmpdir: + with zipfile.ZipFile(zip_path, 'r') as zf: + # Отбираем только файлы с расширением .eps (независимо от регистра) + eps_files = [f for f in zf.namelist() if f.lower().endswith('.eps')] + + for eps_file in eps_files: + # Извлекаем конкретный файл во временную директорию + extracted_path = zf.extract(eps_file, path=tmpdir) + + # Прогоняем через функцию чтения + code_data = read_datamatrix_zxing(extracted_path) + + # Убеждаемся, что код найден и вернулся ожидаемый кортеж + if code_data and isinstance(code_data, tuple): + results.append(code_data) + + return results + +def extract_dm_from_pdf(pdf_path: str) -> list: + """ + Использует extract_barcodes_from_pdf для получения кодов из многостраничного PDF. + Возвращает список кортежей (текст, base64). + """ + results = [] + + # Получаем список словарей с информацией о кодах + barcodes_info = extract_barcodes_from_pdf(pdf_path) + + for info in barcodes_info: + # Извлекаем текст и base64 по ключам + text_val = info.get("text", "") + base64_val = info.get("base64", "") + + results.append((text_val, base64_val)) + + return results + +def save_to_excel(data: list, output_path: str): + """ + Принимает список кортежей (текст, base64) и сохраняет в XLSX файл. + """ + if not data: + print("Нет данных для сохранения в Excel.") + return + + # Формируем DataFrame из списка кортежей + df = pd.DataFrame(data, columns=["Текст", "Base64"]) + + # Сохраняем в XLSX, исключая колонку индексов + df.to_excel(output_path, index=False, engine='openpyxl') + print(f"Данные успешно сохранены в {output_path}") + + +if __name__ == "__main__": + # Тестовый пример оркестрации: + base_dir = os.path.dirname(os.path.abspath(__file__)) + zip_path = "data/0109 черный xxl 720 шт. d46349f7-148a-4301-b6b5-f9a3c70fdf19_begin_offset_2000_number_of_codes_720.zip" + #zip_data = extract_eps_from_zip(zip_path) + + pdf_path = 'data/0109, цвет синий, р.L 10шт_b3ba8577-7874-4dfa-a091-e6953fbe0ca7_gtin_04639970975214_quantity_10.pdf' + pdf_data = extract_dm_from_pdf(pdf_path) diff --git a/build_pdf.py b/build_pdf.py index 03085ad..bf1caec 100644 --- a/build_pdf.py +++ b/build_pdf.py @@ -407,8 +407,8 @@ if __name__ == "__main__": data = read_datamatrix_zxing(image_path) # Замените своими боевыми Base64 строками mock_base64_list = [ - read_datamatrix_zxing(image_path), - read_datamatrix_zxing(image_path) + read_datamatrix_zxing(image_path)[1], + read_datamatrix_zxing(image_path)[1] ] process_batch( diff --git a/read_image.py b/read_image.py index 9990967..70d79bc 100644 --- a/read_image.py +++ b/read_image.py @@ -1,18 +1,53 @@ import zxingcpp as zxing_cpp from PIL import Image import base64 +import fitz -def read_datamatrix_zxing(file_path: str) -> str: - # Открываем изображение через Pillow - img = Image.open(file_path) + +def extract_barcodes_from_pdf(pdf_path: str): + results = [] - # Читаем штрих-код. - # zxing_cpp.read_barcodes умеет работать напрямую с объектами PIL - results = zxing_cpp.read_barcodes(img) + doc = fitz.open(pdf_path) + + for page_num in range(len(doc)): + page = doc[page_num] + + matrix = fitz.Matrix(2.0, 2.0) + pix = page.get_pixmap(matrix=matrix) + + img = Image.frombytes(mode="RGB", size=(pix.width, pix.height), data=pix.samples) + + barcodes = zxing_cpp.read_barcodes(img) + + for barcode in barcodes: + b64_string = base64.b64encode(barcode.bytes).decode('ascii') + results.append({ + "page": page_num + 1, + "text": barcode.text, + "base64": b64_string, + "format": barcode.format.name + }) + + doc.close() + return results + +def read_datamatrix_zxing(file_path: str) -> tuple[str, str]: + # Открываем изображение через Pillow + with Image.open(file_path) as img: + img.load(scale=10) + # Для EPS файлов (и других специфичных форматов) Pillow загружает данные "лениво". + # Чтобы избежать ошибки "does not support the buffer protocol" в zxing, + # нам нужно принудительно загрузить данные и конвертировать их в понятный цветовой режим, + # например, в 'L' (оттенки серого) или 'RGB', который zxing гарантированно поддерживает. + img = img.convert("RGB") + + # Читаем штрих-код. + # zxing_cpp.read_barcodes умеет работать напрямую с объектами PIL + results = zxing_cpp.read_barcodes(img) if not results: print("Коды не найдены на изображении.") - return '' + return ('','') # Берем первый найденный код result = results[0] @@ -24,11 +59,13 @@ def read_datamatrix_zxing(file_path: str) -> str: # b64encode возвращает bytes, поэтому делаем .decode('ascii') для получения строки b64_string = base64.b64encode(raw_bytes).decode('ascii') - return b64_string + return (result.text, b64_string) if __name__ == "__main__": image_path = "data/output.png" - data = read_datamatrix_zxing(image_path) + text, data = read_datamatrix_zxing(image_path) + pdf_read_path = 'data/output_pdfs/Labels_04639970975115.pdf' + results = extract_barcodes_from_pdf(pdf_read_path) if data: print(f"Успешно прочитано: {data}") diff --git a/requirements.txt b/requirements.txt index e994d49..bffa9ca 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,4 +3,5 @@ zxing-cpp reportlab pandas treepoem -openpyxl \ No newline at end of file +openpyxl +pymupdf \ No newline at end of file