# Spork — Usage Guide Spork is a Python library for building print-ready PDFs by layering images together. It was designed for compositing trading cards and tiling them onto pages for printing. ## Requirements ``` pip install reportlab Pillow ``` ## Quick Start ```python from spork import * outfile = NewPDF(8.5, 11) art = ReadPNG("mushroom.png") frame = ReadPNG("PictureFrame.png") outfile.layer(art, 0.5, 0.5, 3.5, 3.5) outfile.layer(frame, 0.5, 0.5, 3.5, 3.5) outfile.save("output.pdf") ``` All coordinates and dimensions are in **inches**. The origin `(0, 0)` is the **top-left** corner of the page. --- ## Loading Images ```python img = ReadPNG("card_art.png") img = ReadJPG("photo.jpg") ``` Both return a `LoadedImage` that can be cropped before layering. --- ## Cropping Images All crop methods modify the image in place and return `self`, so they can be chained. ### Remove pixels from an edge ```python img.CropPixelsL(100) # remove 100px from the left img.CropPixelsR(50) # remove 50px from the right img.CropPixelsT(80) # remove 80px from the top img.CropPixelsB(30) # remove 30px from the bottom ``` ### Keep only pixels from an edge ```python img.KeepPixelsT(500) # keep the top 500px, discard the rest img.KeepPixelsB(500) # keep the bottom 500px img.KeepPixelsL(500) # keep the left 500px img.KeepPixelsR(500) # keep the right 500px ``` ### Make it square ```python img.CropSquare() # trim the longer dimension equally from both sides img.KeepSquare(400) # keep only the center 400x400 pixels ``` ### Chaining ```python art = ReadPNG("wide_photo.png").CropPixelsL(100).CropPixelsR(100).CropSquare() ``` --- ## Creating a PDF ```python outfile = NewPDF(8.5, 11) # width, height in inches (this is US Letter) ``` ### layer(img, x, y, w, h) Place an image on the page. Images are scaled to fit the given width and height. Layers stack in the order they are added — later layers draw on top of earlier ones. ```python outfile.layer(background, 0, 0, 8.5, 11) # full-page background outfile.layer(art, 0.25, 0.25, 2.0, 2.8) # card art outfile.layer(frame, 0.25, 0.25, 2.0, 2.8) # transparent frame on top ``` PNG transparency is preserved — this is how you composite a card from separate art and frame layers. ### fill(color) Fill the entire page with a solid color. Typically used first, as a background. ```python outfile.fill(BLACK) ``` ### line(color, x0, y0, x1, y1, width=1) Draw a straight line between two points. The `width` parameter is in pixels (at 300 DPI, so 1px is a hairline). Useful for crop marks. ```python outfile.line(BLACK, 0.25, 0.0, 0.25, 0.15) # vertical crop mark outfile.line(BLACK, 0.0, 0.25, 0.15, 0.25) # horizontal crop mark outfile.line(RED, 0, 4.0, 8.5, 4.0, width=3) # thicker red guide line ``` ### copy(x0, y0, x1, y1, x2, y2) Copy a rectangular region of the page and paste it at a new position. The rectangle from `(x0, y0)` to `(x1, y1)` is pasted with its top-left corner at `(x2, y2)`. This is how you tile a card across a page — compose it once, then copy it to fill the sheet. ```python # Compose a 2.5 x 3.5 inch card at (0.25, 0.25) outfile.layer(art, 0.25, 0.25, 2.5, 3.5) outfile.layer(frame, 0.25, 0.25, 2.5, 3.5) # Tile it: 3 columns x 3 rows cw = 2.5 # card width ch = 3.5 # card height for row in range(3): for col in range(3): if row == 0 and col == 0: continue # skip the original outfile.copy(0.25, 0.25, 0.25 + cw, 0.25 + ch, 0.25 + col * cw, 0.25 + row * ch) ``` ### save(filename) Render everything and write the PDF. Output is 300 DPI. ```python outfile.save("cards.pdf") ``` --- ## Colors Built-in color constants (all are `(R, G, B)` tuples): | Name | Value | |--------------|-------------------| | `BLACK` | `(0, 0, 0)` | | `WHITE` | `(255, 255, 255)` | | `RED` | `(255, 0, 0)` | | `GREEN` | `(0, 128, 0)` | | `BLUE` | `(0, 0, 255)` | | `YELLOW` | `(255, 255, 0)` | | `CYAN` | `(0, 255, 255)` | | `MAGENTA` | `(255, 0, 255)` | | `GRAY` | `(128, 128, 128)` | | `LIGHT_GRAY` | `(192, 192, 192)` | | `DARK_GRAY` | `(64, 64, 64)` | You can also pass any `(R, G, B)` tuple directly: ```python outfile.fill((30, 30, 30)) outfile.line((255, 128, 0), 0, 0, 8.5, 11) # orange diagonal ``` --- ## Full Example: Trading Card Sheet ```python from spork import * # Load and prep the art art = ReadJPG("dragon.jpg").CropSquare() frame = ReadPNG("card_frame.png") # Create a letter-size page page = NewPDF(8.5, 11) page.fill(WHITE) # Compose one card at top-left (standard poker size: 2.5 x 3.5) page.layer(art, 0.25, 0.25, 2.5, 3.5) page.layer(frame, 0.25, 0.25, 2.5, 3.5) # Tile into a 3x3 grid cw, ch = 2.5, 3.5 for row in range(3): for col in range(3): if row == 0 and col == 0: continue page.copy(0.25, 0.25, 0.25 + cw, 0.25 + ch, 0.25 + col * cw, 0.25 + row * ch) # Add crop marks at each card corner for row in range(4): for col in range(4): x = 0.25 + col * cw y = 0.25 + row * ch page.line(BLACK, x, y - 0.15, x, y + 0.15) page.line(BLACK, x - 0.15, y, x + 0.15, y) page.save("dragon_sheet.pdf") ```