import os
import sys
import zipfile
import tempfile
import subprocess
import shutil
from PIL import Image
from pylibdmtx.pylibdmtx import decode
import fitz # PyMuPDF
import time
# ==============================
# Замер времени: начало
# ==============================
start_time = time.time()
# ==============================
# Настройки
# ==============================
# Папка, где находится скрипт
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) if getattr(sys, 'frozen', False) else os.path.dirname(os.path.abspath(sys.argv[0]))
os.chdir(SCRIPT_DIR)
# Параметры изображения
DPI_PDF = 300 # DPI для PDF
DPI_EPS = 600 # DPI для EPS (маленькие метки)
TARGET_WIDTH_MM = 1.63
TARGET_HEIGHT_MM = 1.63
WIDTH_PX = int(TARGET_WIDTH_MM * DPI_EPS / 25.4)
HEIGHT_PX = int(TARGET_HEIGHT_MM * DPI_EPS / 25.4)
TARGET_WIDTH_MM_PDF = 15
TARGET_HEIGHT_MM_PDF = 15
WIDTH_PX_PDF = int(TARGET_WIDTH_MM_PDF * DPI_PDF / 25.4)
HEIGHT_PX_PDF = int(TARGET_HEIGHT_MM_PDF * DPI_PDF / 25.4)
# Временные папки
TEMP_EXTRACT_ROOT = os.path.join(SCRIPT_DIR, "dm_zip")
TEMP_CONVERT_DIR = os.path.join(SCRIPT_DIR, "temp_converted")
OUTPUT_FILE = "dm_codes.txt"
# Добавлять GS (0x1D) в начало?
FORCE_START_WITH_GS = True
# Удалять временные папки?
CLEAN_UP_TEMP = True
# ==============================
# Проверка Ghostscript (для EPS)
# ==============================
print("Проверка Ghostscript...")
try:
result = subprocess.run(["gswin64c", "--version"], capture_output=True, text=True)
if result.returncode == 0:
print(f"Ghostscript: {result.stdout.strip()}")
else:
raise Exception("Код возврата не 0")
except Exception as e:
print(f"Ghostscript не установлен: {e}")
print("Скачайте с: https://github.com/ArtifexSoftware/ghostpdl-downloads/releases")
input("Нажмите Enter для выхода...")
exit()
# Создаём временную папку
os.makedirs(TEMP_CONVERT_DIR, exist_ok=True)
# ==============================
# Сбор файлов в текущей папке
# ==============================
zip_files = []
pdf_files = []
eps_files = []
for fname in os.listdir(SCRIPT_DIR):
fpath = os.path.join(SCRIPT_DIR, fname)
if os.path.isfile(fpath):
lower = fname.lower()
if lower.endswith(".zip"):
zip_files.append(fpath)
elif lower.endswith(".pdf"):
pdf_files.append(fpath)
elif lower.endswith(".eps"):
eps_files.append(fpath)
print(f"ZIP: {len(zip_files)} | PDF: {len(pdf_files)} | EPS: {len(eps_files)}")
# ==============================
# Список для всех кодов
# ==============================
all_codes = []
# ==============================
# Функция: обработка изображения
# ==============================
def process_image(img):
codes = []
try:
decoded_objects = decode(img)
for obj in decoded_objects:
raw_data = obj.data
if raw_data.startswith(b'\x1d'):
final_data = raw_data
else:
final_data = b'\x1d' + raw_data if FORCE_START_WITH_GS else raw_data
codes.append(final_data)
except Exception as e:
print(f" Ошибка декодирования: {e}")
return codes
# ==============================
# 1. Обработка ZIP-архивов
# ==============================
for zip_path in zip_files:
zip_name = os.path.basename(zip_path)
extract_dir = os.path.join(TEMP_EXTRACT_ROOT, os.path.splitext(zip_name)[0])
os.makedirs(extract_dir, exist_ok=True)
print(f"\nРаспаковка: {zip_name}")
try:
with zipfile.ZipFile(zip_path, 'r') as z:
z.extractall(extract_dir)
print(f" Архив распакован")
except Exception as e:
print(f" Ошибка распаковки: {e}")
continue
for root, _, files in os.walk(extract_dir):
for fname in files:
fpath = os.path.join(root, fname)
lower = fname.lower()
try:
if lower.endswith(".pdf"):
print(f" PDF из ZIP: {fname}")
doc = fitz.open(fpath)
for page_num in range(len(doc)):
mat = fitz.Matrix(DPI_PDF / 72, DPI_PDF / 72) # Масштаб по DPI
pix = doc[page_num].get_pixmap(matrix=mat)
img = Image.frombytes("RGB", [pix.width, pix.height], pix.samples)
img = img.convert('L') # Grayscale
#img = img.resize((WIDTH_PX_PDF, HEIGHT_PX_PDF), Image.LANCZOS)
all_codes.extend(process_image(img))
doc.close()
elif lower.endswith(".eps"):
print(f" EPS из ZIP: {fname}")
temp_png = os.path.join(TEMP_CONVERT_DIR, f"zip_{fname}.png")
gs_cmd = [
"gswin64c", "-dBATCH", "-dNOPAUSE", "-dSAFER",
f"-r{DPI_EPS}", "-sDEVICE=pnggray",
f"-dDEVICEWIDTHPOINTS={WIDTH_PX}", f"-dDEVICEHEIGHTPOINTS={HEIGHT_PX}",
"-dPDFFitPage", "-dTextAlphaBits=1", "-dGraphicsAlphaBits=1",
f"-sOutputFile={temp_png}", fpath
]
res = subprocess.run(gs_cmd, capture_output=True, text=True, encoding='utf-8')
if res.returncode != 0:
print(f" GS ошибка: {res.stderr[:100]}...")
else:
img = Image.open(temp_png).convert('L')
all_codes.extend(process_image(img))
except Exception as e:
print(f" Ошибка: {e}")
# ==============================
# 2. Обработка PDF и EPS напрямую
# ==============================
for fpath in pdf_files + eps_files:
fname = os.path.basename(fpath)
print(f"Прямой файл: {fname}")
try:
if fname.lower().endswith(".pdf"):
doc = fitz.open(fpath)
for page_num in range(len(doc)):
mat = fitz.Matrix(DPI_PDF / 72, DPI_PDF / 72)
pix = doc[page_num].get_pixmap(matrix=mat)
img = Image.frombytes("RGB", [pix.width, pix.height], pix.samples)
img = img.convert('L')
#img = img.resize((WIDTH_PX_PDF, HEIGHT_PX_PDF), Image.LANCZOS)
all_codes.extend(process_image(img))
doc.close()
elif fname.lower().endswith(".eps"):
temp_png = os.path.join(TEMP_CONVERT_DIR, f"direct_{fname}.png")
gs_cmd = [
"gswin64c", "-dBATCH", "-dNOPAUSE", "-dSAFER",
f"-r{DPI_EPS}", "-sDEVICE=pnggray",
f"-dDEVICEWIDTHPOINTS={WIDTH_PX}", f"-dDEVICEHEIGHTPOINTS={HEIGHT_PX}",
"-dPDFFitPage", "-dTextAlphaBits=1", "-dGraphicsAlphaBits=1",
f"-sOutputFile={temp_png}", fpath
]
res = subprocess.run(gs_cmd, capture_output=True, text=True, encoding='utf-8')
if res.returncode != 0:
print(f" GS ошибка: {res.stderr[:100]}...")
else:
img = Image.open(temp_png).convert('L')
all_codes.extend(process_image(img))
except Exception as e:
print(f" Ошибка: {e}")
# ==============================
# Сохранение всех кодов
# ==============================
with open(OUTPUT_FILE, "wb") as f:
for code in all_codes:
f.write(code + b'\n')
print(f"\nГотово!")
print(f"ZIP: {len(zip_files)} | PDF/EPS: {len(pdf_files) + len(eps_files)}")
print(f"Всего найдено кодов: {len(all_codes)}")
print(f"Результат: {OUTPUT_FILE}")
# ==============================
# Удаление временных папок
# ==============================
if CLEAN_UP_TEMP:
print("\nУдаление временных папок...")
try:
if os.path.exists(TEMP_CONVERT_DIR):
shutil.rmtree(TEMP_CONVERT_DIR, ignore_errors=True)
print(f" Удалено: {TEMP_CONVERT_DIR}")
except Exception as e:
print(f" Ошибка удаления {TEMP_CONVERT_DIR}: {e}")
try:
if os.path.exists(TEMP_EXTRACT_ROOT):
shutil.rmtree(TEMP_EXTRACT_ROOT, ignore_errors=True)
print(f" Удалено: {TEMP_EXTRACT_ROOT}")
except Exception as e:
print(f" Ошибка удаления {TEMP_EXTRACT_ROOT}: {e}")
# ==============================
# Время выполнения
# ==============================
end_time = time.time()
total_time = end_time - start_time
hours, rem = divmod(total_time, 3600)
minutes, seconds = divmod(rem, 60)
time_str = "{:02}:{:02}:{:02}".format(int(hours), int(minutes), int(seconds))
print(f"\n⏱ Время работы скрипта: {time_str}")
# Завершение
input("\nНажмите Enter для выхода...")