initial webapp draft
This commit is contained in:
commit
4f2723b767
22 changed files with 713 additions and 0 deletions
87
cost_calculator.py
Normal file
87
cost_calculator.py
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
# cost_calculator.py
|
||||
import os
|
||||
from PyPDF2 import PdfReader
|
||||
from pdf2image import convert_from_path
|
||||
import numpy as np
|
||||
|
||||
UPLOAD_FOLDER = "data/uploads"
|
||||
ALLOWED_EXTENSIONS = {"pdf"}
|
||||
|
||||
|
||||
def allowed_file(filename: str) -> bool:
|
||||
return "." in filename and filename.rsplit(".", 1)[1].lower() in ALLOWED_EXTENSIONS
|
||||
|
||||
|
||||
def points_to_meters(points: float) -> float:
|
||||
return (points / 72.0) * 0.0254
|
||||
|
||||
|
||||
def get_rate_black() -> float:
|
||||
return float(os.environ.get("RATE_PER_M2_BLACK", "4.0"))
|
||||
|
||||
|
||||
def get_rate_color() -> float:
|
||||
return float(os.environ.get("RATE_PER_M2_COLOR", "5.0"))
|
||||
|
||||
|
||||
def analyze_pdf(path, compute_ink=True):
|
||||
reader = PdfReader(path)
|
||||
pages_info = []
|
||||
total_area_black = total_area_color = 0.0
|
||||
total_cost_black = total_cost_color = 0.0
|
||||
|
||||
for i, page in enumerate(reader.pages):
|
||||
box = page.mediabox
|
||||
width_m = points_to_meters(float(box.width))
|
||||
height_m = points_to_meters(float(box.height))
|
||||
area = width_m * height_m
|
||||
|
||||
ink_pct = None
|
||||
is_color = False
|
||||
|
||||
if compute_ink:
|
||||
try:
|
||||
images = convert_from_path(path, first_page=i + 1, last_page=i + 1, dpi=150)
|
||||
img = images[0].convert("RGB")
|
||||
arr = np.array(img)
|
||||
|
||||
# ink pixels: any channel < 240
|
||||
ink_mask = np.any(arr < 240, axis=2)
|
||||
ink_pct = float(np.count_nonzero(ink_mask)) / (arr.shape[0] * arr.shape[1]) * 100.0
|
||||
|
||||
# simple color detection: if RGB channels differ significantly
|
||||
avg_rgb = arr.mean(axis=(0, 1))
|
||||
if np.ptp(avg_rgb) > 30:
|
||||
is_color = True
|
||||
except Exception as e:
|
||||
print(f"Page {i+1} ink/color calc failed: {e}")
|
||||
ink_pct = None
|
||||
|
||||
if is_color:
|
||||
rate = get_rate_color()
|
||||
total_area_color += area
|
||||
total_cost_color += area * rate
|
||||
else:
|
||||
rate = get_rate_black()
|
||||
total_area_black += area
|
||||
total_cost_black += area * rate
|
||||
|
||||
pages_info.append({
|
||||
"page": i + 1,
|
||||
"width_m": width_m,
|
||||
"height_m": height_m,
|
||||
"area_m2": area,
|
||||
"ink_pct": ink_pct,
|
||||
"is_color": is_color,
|
||||
"cost": round(area * rate, 2)
|
||||
})
|
||||
|
||||
return {
|
||||
"filename": os.path.basename(path),
|
||||
"pages": pages_info,
|
||||
"total_area_black": total_area_black,
|
||||
"total_area_color": total_area_color,
|
||||
"total_cost_black": round(total_cost_black, 2),
|
||||
"total_cost_color": round(total_cost_color, 2),
|
||||
"grand_total": round(total_cost_black + total_cost_color, 2)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue