import pydicom import numpy as np from PIL import Image import time from datetime import datetime from reportlab.pdfgen import canvas from reportlab.lib.pagesizes import letter from reportlab.lib.units import inch def load_dicom(filepath): """ Reads a DICOM file and returns a PIL Image. """ dicom = pydicom.dcmread(filepath) # Extract the pixel array pixel_array = dicom.pixel_array.astype(float) # Normalize to 0-255 range pixel_min = pixel_array.min() pixel_max = pixel_array.max() normalized = (pixel_array - pixel_min) / (pixel_max - pixel_min) * 255 # Convert to uint8 RGB image image = Image.fromarray(normalized.astype(np.uint8)).convert("RGB") return image def generate_pdf(report_text): """ Takes report text, returns path to a saved PDF file. """ if not report_text or not report_text.strip(): return None filename = f"brain_mri_report_{int(time.time())}.pdf" path = f"/tmp/{filename}" c = canvas.Canvas(path, pagesize=letter) width, height = letter left_margin = 0.75 * inch top_margin = height - 0.75 * inch line_height = 16 max_width = width - 2 * left_margin # Title c.setFont("Helvetica-Bold", 14) c.drawString(left_margin, top_margin, "Brain MRI Radiology Report") # Date c.setFont("Helvetica", 9) c.drawString(left_margin, top_margin - 16, f"Generated: {datetime.now().strftime('%Y-%m-%d %H:%M')}") # Divider line c.line(left_margin, top_margin - 24, width - left_margin, top_margin - 24) y = top_margin - 0.55 * inch # Write report body line by line c.setFont("Helvetica", 11) for paragraph in report_text.split("\n"): words = paragraph.split(" ") line = "" for word in words: test = (line + " " + word).strip() if c.stringWidth(test, "Helvetica", 11) <= max_width: line = test else: if y < 0.75 * inch: # new page if near bottom c.showPage() c.setFont("Helvetica", 11) y = height - 0.75 * inch c.drawString(left_margin, y, line) y -= line_height line = word # Draw remaining line if y < 0.75 * inch: c.showPage() c.setFont("Helvetica", 11) y = height - 0.75 * inch c.drawString(left_margin, y, line) y -= line_height c.save() return path