Forked from
Forked from
test-fixtures / generate_fixtures.py
test-fixtures / generate_fixtures.py
"""
ΠΠ΅Π½Π΅ΡΠ°ΡΠΈΡ ΡΠ΅ΡΡΠΎΠ²ΡΡ
ΡΠ°ΠΉΠ»ΠΎΠ² (PNG + PDF) Π½Π° Π°Π½Π³Π»ΠΈΠΉΡΠΊΠΎΠΌ ΠΈ ΡΡΡΡΠΊΠΎΠΌ ΡΠ·ΡΠΊΠ°Ρ
.
ΠΠ°ΠΏΡΡΠΊ: python test-fixtures/generate_fixtures.py
"""
import os
from PIL import Image, ImageDraw, ImageFont
from fpdf import FPDF
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
def get_font(size: int = 40) -> ImageFont.truetype:
"""ΠΠΎΠ»ΡΡΠΈΡΡ ΡΡΠΈΡΡ, ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°ΡΡΠΈΠΉ ΠΊΠΈΡΠΈΠ»Π»ΠΈΡΡ (Windows)."""
candidates = [
"C:/Windows/Fonts/arial.ttf",
"C:/Windows/Fonts/calibri.ttf",
"C:/Windows/Fonts/times.ttf",
"C:/Windows/Fonts/verdana.ttf",
]
for path in candidates:
if os.path.exists(path):
return ImageFont.truetype(path, size)
return ImageFont.load_default()
def create_text_image(text: str, output_path: str) -> None:
"""Π‘ΠΎΠ·Π΄Π°ΡΡ PNG-ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ Ρ ΡΠ΅ΠΊΡΡΠΎΠΌ Π½Π° Π±Π΅Π»ΠΎΠΌ ΡΠΎΠ½Π΅."""
font = get_font(48)
tmp_img = Image.new("RGB", (100, 100), "white")
tmp_draw = ImageDraw.Draw(tmp_img)
bbox = tmp_draw.textbbox((0, 0), text, font=font)
text_w = bbox[2] - bbox[0]
text_h = bbox[3] - bbox[1]
padding = 60
img_w = text_w + padding * 2
img_h = text_h + padding * 2
img = Image.new("RGB", (img_w, img_h), "white")
draw = ImageDraw.Draw(img)
draw.text((padding, padding), text, fill="black", font=font)
img.save(output_path, "PNG")
print(f" Created: {output_path} ({img_w}x{img_h})")
def create_text_pdf(text: str, output_path: str) -> None:
"""Π‘ΠΎΠ·Π΄Π°ΡΡ PDF Ρ ΡΠ΅ΠΊΡΡΠΎΠΌ. ΠΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ Π²ΡΡΡΠΎΠ΅Π½Π½ΡΠΉ ΡΡΠΈΡΡ + Unicode."""
pdf = FPDF()
pdf.add_page()
# ΠΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ ΡΡΠΈΡΡ, ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°ΡΡΠΈΠΉ ΠΊΠΈΡΠΈΠ»Π»ΠΈΡΡ
font_path = None
for candidate in [
"C:/Windows/Fonts/arial.ttf",
"C:/Windows/Fonts/calibri.ttf",
"C:/Windows/Fonts/times.ttf",
]:
if os.path.exists(candidate):
font_path = candidate
break
if font_path:
pdf.add_font("TestFont", "", font_path, uni=True)
pdf.set_font("TestFont", size=14)
else:
pdf.set_font("Helvetica", size=14)
pdf.multi_cell(0, 10, text)
pdf.output(output_path)
print(f" Created: {output_path}")
def create_image_pdf(text: str, output_path: str) -> None:
"""Π‘ΠΎΠ·Π΄Π°ΡΡ PDF Π±Π΅Π· ΡΠ΅ΠΊΡΡΠΎΠ²ΠΎΠ³ΠΎ ΡΠ»ΠΎΡ β ΡΠ΅ΠΊΡΡ ΡΠ΅Π½Π΄Π΅ΡΠΈΡΡΡ ΠΊΠ°ΠΊ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅."""
# Π‘Π½Π°ΡΠ°Π»Π° ΡΠΎΠ·Π΄Π°ΡΠΌ ΠΊΠ°ΡΡΠΈΠ½ΠΊΡ Ρ ΡΠ΅ΠΊΡΡΠΎΠΌ
font = get_font(36)
tmp_img = Image.new("RGB", (100, 100), "white")
tmp_draw = ImageDraw.Draw(tmp_img)
bbox = tmp_draw.textbbox((0, 0), text, font=font)
text_w = bbox[2] - bbox[0]
text_h = bbox[3] - bbox[1]
padding = 40
img_w = text_w + padding * 2
img_h = text_h + padding * 2
img = Image.new("RGB", (img_w, img_h), "white")
draw = ImageDraw.Draw(img)
draw.text((padding, padding), text, fill="black", font=font)
# Π‘ΠΎΡ
ΡΠ°Π½ΡΠ΅ΠΌ ΠΊΠ°ΠΊ Π²ΡΠ΅ΠΌΠ΅Π½Π½ΡΠΉ PNG ΠΈ Π²ΡΡΡΠ°ΠΈΠ²Π°Π΅ΠΌ Π² PDF ΠΊΠ°ΠΊ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅
tmp_png = output_path + ".tmp.png"
img.save(tmp_png, "PNG")
pdf = FPDF()
pdf.add_page()
# ΠΡΡΡΠ°ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ β PDF Π½Π΅ Π±ΡΠ΄Π΅Ρ ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΡ ΡΠ΅ΠΊΡΡΠΎΠ²ΠΎΠ³ΠΎ ΡΠ»ΠΎΡ
pdf.image(tmp_png, x=10, y=10, w=img_w * 0.5)
pdf.output(output_path)
# Π£Π΄Π°Π»ΡΠ΅ΠΌ Π²ΡΠ΅ΠΌΠ΅Π½Π½ΡΠΉ ΡΠ°ΠΉΠ»
os.remove(tmp_png)
print(f" Created: {output_path} (image-only PDF, no text layer)")
def main():
print("Generating test fixtures...\n")
# === PNG images ===
print("[PNG] Creating test images...")
create_text_image(
"Hello World OCR Test",
os.path.join(SCRIPT_DIR, "sample_eng.png"),
)
create_text_image(
"ΠΡΠΈΠ²Π΅Ρ ΠΌΠΈΡ ΡΠ΅ΡΡ ΡΠ°ΡΠΏΠΎΠ·Π½Π°Π²Π°Π½ΠΈΡ",
os.path.join(SCRIPT_DIR, "sample_rus.png"),
)
# === PDF files ===
print("\n[PDF] Creating test PDFs...")
create_text_pdf(
"This is an English PDF document.\n"
"It contains sample text for testing PDF parsing.\n"
"The quick brown fox jumps over the lazy dog.",
os.path.join(SCRIPT_DIR, "sample_eng.pdf"),
)
create_text_pdf(
"ΠΡΠΎ ΡΡΡΡΠΊΠΈΠΉ PDF Π΄ΠΎΠΊΡΠΌΠ΅Π½Ρ.\n"
"ΠΠ½ ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ ΠΏΡΠΈΠΌΠ΅Ρ ΡΠ΅ΠΊΡΡΠ° Π΄Π»Ρ ΡΠ΅ΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΠΏΠ°ΡΡΠΈΠ½Π³Π° PDF.\n"
"Π‘ΡΠ΅ΡΡ Π΅ΡΡ ΡΡΠΈΡ
ΠΌΡΠ³ΠΊΠΈΡ
ΡΡΠ°Π½ΡΡΠ·ΡΠΊΠΈΡ
Π±ΡΠ»ΠΎΠΊ, Π΄Π° Π²ΡΠΏΠ΅ΠΉ ΡΠ°Ρ.",
os.path.join(SCRIPT_DIR, "sample_rus.pdf"),
)
# === Mixed language (EN+RU) files ===
print("\n[MIX] Creating mixed-language test files...")
# 1. Mixed image (EN + RU text)
create_text_image(
"Hello ΠΡΠΈΠ²et World ΠΠΈΡ OCR Test",
os.path.join(SCRIPT_DIR, "sample_mix.png"),
)
# 2. Mixed PDF with text layer (selectable text)
create_text_pdf(
"This is a mixed language document.\n"
"ΠΡΠΎ Π΄ΠΎΠΊΡΠΌΠ΅Π½Ρ Π½Π° Π΄Π²ΡΡ
ΡΠ·ΡΠΊΠ°Ρ
.\n"
"The quick brown fox jumps over the lazy dog.\n"
"Π‘ΡΠ΅ΡΡ Π΅ΡΡ ΡΡΠΈΡ
ΠΌΡΠ³ΠΊΠΈΡ
ΡΡΠ°Π½ΡΡΠ·ΡΠΊΠΈΡ
Π±ΡΠ»ΠΎΠΊ, Π΄Π° Π²ΡΠΏΠ΅ΠΉ ΡΠ°Ρ.",
os.path.join(SCRIPT_DIR, "sample_mix_text.pdf"),
)
# 3. Mixed PDF without text layer (image-only β rendered as image in PDF)
create_image_pdf(
"Hello ΠΡΠΈΠ²et World ΠΠΈΡ Mixed OCR Test for bilingual document recognition",
os.path.join(SCRIPT_DIR, "sample_mix_ocr.pdf"),
)
print("\nDone! All test fixtures generated.")
if __name__ == "__main__":
main()"""
ΠΠ΅Π½Π΅ΡΠ°ΡΠΈΡ ΡΠ΅ΡΡΠΎΠ²ΡΡ
ΡΠ°ΠΉΠ»ΠΎΠ² (PNG + PDF) Π½Π° Π°Π½Π³Π»ΠΈΠΉΡΠΊΠΎΠΌ ΠΈ ΡΡΡΡΠΊΠΎΠΌ ΡΠ·ΡΠΊΠ°Ρ
.
ΠΠ°ΠΏΡΡΠΊ: python test-fixtures/generate_fixtures.py
"""
import os
from PIL import Image, ImageDraw, ImageFont
from fpdf import FPDF
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
def get_font(size: int = 40) -> ImageFont.truetype:
"""ΠΠΎΠ»ΡΡΠΈΡΡ ΡΡΠΈΡΡ, ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°ΡΡΠΈΠΉ ΠΊΠΈΡΠΈΠ»Π»ΠΈΡΡ (Windows)."""
candidates = [
"C:/Windows/Fonts/arial.ttf",
"C:/Windows/Fonts/calibri.ttf",
"C:/Windows/Fonts/times.ttf",
"C:/Windows/Fonts/verdana.ttf",
]
for path in candidates:
if os.path.exists(path):
return ImageFont.truetype(path, size)
return ImageFont.load_default()
def create_text_image(text: str, output_path: str) -> None:
"""Π‘ΠΎΠ·Π΄Π°ΡΡ PNG-ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ Ρ ΡΠ΅ΠΊΡΡΠΎΠΌ Π½Π° Π±Π΅Π»ΠΎΠΌ ΡΠΎΠ½Π΅."""
font = get_font(48)
tmp_img = Image.new("RGB", (100, 100), "white")
tmp_draw = ImageDraw.Draw(tmp_img)
bbox = tmp_draw.textbbox((0, 0), text, font=font)
text_w = bbox[2] - bbox[0]
text_h = bbox[3] - bbox[1]
padding = 60
img_w = text_w + padding * 2
img_h = text_h + padding * 2
img = Image.new("RGB", (img_w, img_h), "white")
draw = ImageDraw.Draw(img)
draw.text((padding, padding), text, fill="black", font=font)
img.save(output_path, "PNG")
print(f" Created: {output_path} ({img_w}x{img_h})")
def create_text_pdf(text: str, output_path: str) -> None:
"""Π‘ΠΎΠ·Π΄Π°ΡΡ PDF Ρ ΡΠ΅ΠΊΡΡΠΎΠΌ. ΠΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ Π²ΡΡΡΠΎΠ΅Π½Π½ΡΠΉ ΡΡΠΈΡΡ + Unicode."""
pdf = FPDF()
pdf.add_page()
# ΠΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ ΡΡΠΈΡΡ, ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°ΡΡΠΈΠΉ ΠΊΠΈΡΠΈΠ»Π»ΠΈΡΡ
font_path = None
for candidate in [
"C:/Windows/Fonts/arial.ttf",
"C:/Windows/Fonts/calibri.ttf",
"C:/Windows/Fonts/times.ttf",
]:
if os.path.exists(candidate):
font_path = candidate
break
if font_path:
pdf.add_font("TestFont", "", font_path, uni=True)
pdf.set_font("TestFont", size=14)
else:
pdf.set_font("Helvetica", size=14)
pdf.multi_cell(0, 10, text)
pdf.output(output_path)
print(f" Created: {output_path}")
def create_image_pdf(text: str, output_path: str) -> None:
"""Π‘ΠΎΠ·Π΄Π°ΡΡ PDF Π±Π΅Π· ΡΠ΅ΠΊΡΡΠΎΠ²ΠΎΠ³ΠΎ ΡΠ»ΠΎΡ β ΡΠ΅ΠΊΡΡ ΡΠ΅Π½Π΄Π΅ΡΠΈΡΡΡ ΠΊΠ°ΠΊ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅."""
# Π‘Π½Π°ΡΠ°Π»Π° ΡΠΎΠ·Π΄Π°ΡΠΌ ΠΊΠ°ΡΡΠΈΠ½ΠΊΡ Ρ ΡΠ΅ΠΊΡΡΠΎΠΌ
font = get_font(36)
tmp_img = Image.new("RGB", (100, 100), "white")
tmp_draw = ImageDraw.Draw(tmp_img)
bbox = tmp_draw.textbbox((0, 0), text, font=font)
text_w = bbox[2] - bbox[0]
text_h = bbox[3] - bbox[1]
padding = 40
img_w = text_w + padding * 2
img_h = text_h + padding * 2
img = Image.new("RGB", (img_w, img_h), "white")
draw = ImageDraw.Draw(img)
draw.text((padding, padding), text, fill="black", font=font)
# Π‘ΠΎΡ
ΡΠ°Π½ΡΠ΅ΠΌ ΠΊΠ°ΠΊ Π²ΡΠ΅ΠΌΠ΅Π½Π½ΡΠΉ PNG ΠΈ Π²ΡΡΡΠ°ΠΈΠ²Π°Π΅ΠΌ Π² PDF ΠΊΠ°ΠΊ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅
tmp_png = output_path + ".tmp.png"
img.save(tmp_png, "PNG")
pdf = FPDF()
pdf.add_page()
# ΠΡΡΡΠ°ΠΈΠ²Π°Π΅ΠΌ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ β PDF Π½Π΅ Π±ΡΠ΄Π΅Ρ ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΡ ΡΠ΅ΠΊΡΡΠΎΠ²ΠΎΠ³ΠΎ ΡΠ»ΠΎΡ
pdf.image(tmp_png, x=10, y=10, w=img_w * 0.5)
pdf.output(output_path)
# Π£Π΄Π°Π»ΡΠ΅ΠΌ Π²ΡΠ΅ΠΌΠ΅Π½Π½ΡΠΉ ΡΠ°ΠΉΠ»
os.remove(tmp_png)
print(f" Created: {output_path} (image-only PDF, no text layer)")
def main():
print("Generating test fixtures...\n")
# === PNG images ===
print("[PNG] Creating test images...")
create_text_image(
"Hello World OCR Test",
os.path.join(SCRIPT_DIR, "sample_eng.png"),
)
create_text_image(
"ΠΡΠΈΠ²Π΅Ρ ΠΌΠΈΡ ΡΠ΅ΡΡ ΡΠ°ΡΠΏΠΎΠ·Π½Π°Π²Π°Π½ΠΈΡ",
os.path.join(SCRIPT_DIR, "sample_rus.png"),
)
# === PDF files ===
print("\n[PDF] Creating test PDFs...")
create_text_pdf(
"This is an English PDF document.\n"
"It contains sample text for testing PDF parsing.\n"
"The quick brown fox jumps over the lazy dog.",
os.path.join(SCRIPT_DIR, "sample_eng.pdf"),
)
create_text_pdf(
"ΠΡΠΎ ΡΡΡΡΠΊΠΈΠΉ PDF Π΄ΠΎΠΊΡΠΌΠ΅Π½Ρ.\n"
"ΠΠ½ ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ ΠΏΡΠΈΠΌΠ΅Ρ ΡΠ΅ΠΊΡΡΠ° Π΄Π»Ρ ΡΠ΅ΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΠΏΠ°ΡΡΠΈΠ½Π³Π° PDF.\n"
"Π‘ΡΠ΅ΡΡ Π΅ΡΡ ΡΡΠΈΡ
ΠΌΡΠ³ΠΊΠΈΡ
ΡΡΠ°Π½ΡΡΠ·ΡΠΊΠΈΡ
Π±ΡΠ»ΠΎΠΊ, Π΄Π° Π²ΡΠΏΠ΅ΠΉ ΡΠ°Ρ.",
os.path.join(SCRIPT_DIR, "sample_rus.pdf"),
)
# === Mixed language (EN+RU) files ===
print("\n[MIX] Creating mixed-language test files...")
# 1. Mixed image (EN + RU text)
create_text_image(
"Hello ΠΡΠΈΠ²et World ΠΠΈΡ OCR Test",
os.path.join(SCRIPT_DIR, "sample_mix.png"),
)
# 2. Mixed PDF with text layer (selectable text)
create_text_pdf(
"This is a mixed language document.\n"
"ΠΡΠΎ Π΄ΠΎΠΊΡΠΌΠ΅Π½Ρ Π½Π° Π΄Π²ΡΡ
ΡΠ·ΡΠΊΠ°Ρ
.\n"
"The quick brown fox jumps over the lazy dog.\n"
"Π‘ΡΠ΅ΡΡ Π΅ΡΡ ΡΡΠΈΡ
ΠΌΡΠ³ΠΊΠΈΡ
ΡΡΠ°Π½ΡΡΠ·ΡΠΊΠΈΡ
Π±ΡΠ»ΠΎΠΊ, Π΄Π° Π²ΡΠΏΠ΅ΠΉ ΡΠ°Ρ.",
os.path.join(SCRIPT_DIR, "sample_mix_text.pdf"),
)
# 3. Mixed PDF without text layer (image-only β rendered as image in PDF)
create_image_pdf(
"Hello ΠΡΠΈΠ²et World ΠΠΈΡ Mixed OCR Test for bilingual document recognition",
os.path.join(SCRIPT_DIR, "sample_mix_ocr.pdf"),
)
print("\nDone! All test fixtures generated.")
if __name__ == "__main__":
main()