{"id":317,"date":"2026-06-03T20:08:05","date_gmt":"2026-06-03T20:08:05","guid":{"rendered":"https:\/\/memoria-cards.fr\/?page_id=317"},"modified":"2026-06-21T10:12:35","modified_gmt":"2026-06-21T10:12:35","slug":"building-memoria-cards-how-i-rewrote-my-software-pipeline-three-times-and-finally-got-it-right","status":"publish","type":"page","link":"https:\/\/memoria-cards.fr\/?page_id=317","title":{"rendered":"Building Memoria Cards \nHow I Rewrote My Software Pipeline Three Times (And Finally Got It Right)"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"has-base-color has-black-gradient-background has-text-color has-background has-link-color wp-elements-98a91de4cbd47f1d966912f3ac31ace8 wp-block-paragraph\" style=\"border-top-left-radius:var(--wp--preset--border-radius--md);border-top-right-radius:var(--wp--preset--border-radius--md);border-bottom-left-radius:var(--wp--preset--border-radius--md);border-bottom-right-radius:var(--wp--preset--border-radius--md)\">Making physical trading cards at home sounds simple enough. Design a template, add some art, print it out. But if you want to do it <em>right<\/em> with consistent quality, scalable production, and clean print output the software side turns out to be a rabbit hole of its own. Here&rsquo;s how my pipeline evolved over two years, from shaky Photoshop experiments to a fully parametric SVG factory.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Phase 1: The Idea Takes Shape in Photoshop<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">It started with a familiar itch: I wanted video game\u2013themed trading cards. Nothing commercial existed that quite scratched it, so I figured I&rsquo;d make my own.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I opened Photoshop and started building templates. The vibe was right, the illustrations clicked into place, the DNA of what would become Memoria Cards was already there. Then I stopped. Life moved on, the files sat idle.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">But there was a deeper problem I hadn&rsquo;t fully admitted yet: I am genuinely disorganized in Photoshop. Layer structures would drift. Each new card became a slightly different version of the template. Nothing was standardized. The moment I&rsquo;d want to change a font, a color, a layout element&#8230; I&rsquo;d have to hunt it down manually across a dozen separate files. It wasn&rsquo;t sustainable for even a small run of cards, let alone a real catalog.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full wp-duotone-unset-1\"><img loading=\"lazy\" decoding=\"async\" width=\"872\" height=\"454\" src=\"https:\/\/memoria-cards.fr\/wp-content\/uploads\/2026\/05\/image.png\" alt=\"\" class=\"wp-image-188\" srcset=\"https:\/\/memoria-cards.fr\/wp-content\/uploads\/2026\/05\/image.png 872w, https:\/\/memoria-cards.fr\/wp-content\/uploads\/2026\/05\/image-300x156.png 300w, https:\/\/memoria-cards.fr\/wp-content\/uploads\/2026\/05\/image-768x400.png 768w\" sizes=\"auto, (max-width: 872px) 100vw, 872px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Phase 2: A Python Pipeline with Pillow<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The itch came back, stronger this time, and with it a new idea: automate the whole thing with Python.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I built a set of scripts using the Pillow imaging library. Cards were generated programmatically, each one assembled from components: illustrations, rounded rectangles, stat bars, text layers. I added small visual touches like noise effects and soft drop shadows. A masking and cropping system kept the card frame crisp. For the first time, I could generate a card from a YAML description without touching any image editor.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It felt like a real step forward. I even got a batch printed through MPC, and they looked&#8230; decent.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-style-rounded wp-duotone-unset-2\"><img loading=\"lazy\" decoding=\"async\" width=\"849\" height=\"371\" src=\"https:\/\/memoria-cards.fr\/wp-content\/uploads\/2026\/05\/image-1.png\" alt=\"\" class=\"wp-image-189\" srcset=\"https:\/\/memoria-cards.fr\/wp-content\/uploads\/2026\/05\/image-1.png 849w, https:\/\/memoria-cards.fr\/wp-content\/uploads\/2026\/05\/image-1-300x131.png 300w, https:\/\/memoria-cards.fr\/wp-content\/uploads\/2026\/05\/image-1-768x336.png 768w\" sizes=\"auto, (max-width: 849px) 100vw, 849px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large wp-duotone-unset-3\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"692\" src=\"https:\/\/memoria-cards.fr\/wp-content\/uploads\/2026\/05\/image-2-1024x692.png\" alt=\"\" class=\"wp-image-190\" srcset=\"https:\/\/memoria-cards.fr\/wp-content\/uploads\/2026\/05\/image-2-1024x692.png 1024w, https:\/\/memoria-cards.fr\/wp-content\/uploads\/2026\/05\/image-2-300x203.png 300w, https:\/\/memoria-cards.fr\/wp-content\/uploads\/2026\/05\/image-2-768x519.png 768w, https:\/\/memoria-cards.fr\/wp-content\/uploads\/2026\/05\/image-2-1536x1038.png 1536w, https:\/\/memoria-cards.fr\/wp-content\/uploads\/2026\/05\/image-2-1320x892.png 1320w, https:\/\/memoria-cards.fr\/wp-content\/uploads\/2026\/05\/image-2.png 1582w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">But the pipeline had real structural problems:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Maintenance was painful.<\/strong> Pillow is a low-level raster library. Every visual tweak meant digging back into pixel-math code. There was no template in any meaningful sense : just a very long script.<\/li>\n\n\n\n<li><strong>Typography was terrible for print.<\/strong> The only way to get sharp text was to render at 3\u00d7 resolution and downscale. This is a hack, and it showed. Print-ready files need true vector text, not downsampled raster approximations. The whole approach was fundamentally misaligned with what high-quality printing actually requires.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The printed cards were fine for a prototype. But I knew this wasn&rsquo;t the foundation to build on.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Phase 3: SVG Changes Everything<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Then a thought clicked: <em>SVG is just XML. I can manipulate it programmatically.<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I rebuilt the entire pipeline from scratch around Inkscape and SVG. The shift in approach was total.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Now, I design my card template in Inkscape like a proper designer with full visual control, proper typography, clean geometry. Every element that needs to vary gets a unique <code>id<\/code>. Then a Python script walks the SVG tree, swaps out attribute values and text nodes, injects illustration paths, and writes a new file. SVG 2 also offers a handful of native filter effects (noise, blur, color transforms) that replace all my old Pillow hacks with clean, resolution-independent declarations.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large wp-duotone-unset-4\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"525\" src=\"https:\/\/memoria-cards.fr\/wp-content\/uploads\/2026\/05\/image-4-1024x525.png\" alt=\"\" class=\"wp-image-192\" srcset=\"https:\/\/memoria-cards.fr\/wp-content\/uploads\/2026\/05\/image-4-1024x525.png 1024w, https:\/\/memoria-cards.fr\/wp-content\/uploads\/2026\/05\/image-4-300x154.png 300w, https:\/\/memoria-cards.fr\/wp-content\/uploads\/2026\/05\/image-4-768x394.png 768w, https:\/\/memoria-cards.fr\/wp-content\/uploads\/2026\/05\/image-4-1536x787.png 1536w, https:\/\/memoria-cards.fr\/wp-content\/uploads\/2026\/05\/image-4-1320x677.png 1320w, https:\/\/memoria-cards.fr\/wp-content\/uploads\/2026\/05\/image-4.png 1910w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The result is a <strong>Template Factory<\/strong>: a parametric system where each card is a rendered instance of a model, not a hand-crafted Photoshop file. The same mechanism generates print sheets multiple cards laid out on a single page, ready to send to the printer.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large wp-duotone-unset-5\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"511\" src=\"https:\/\/memoria-cards.fr\/wp-content\/uploads\/2026\/05\/image-3-1024x511.png\" alt=\"\" class=\"wp-image-191\" srcset=\"https:\/\/memoria-cards.fr\/wp-content\/uploads\/2026\/05\/image-3-1024x511.png 1024w, https:\/\/memoria-cards.fr\/wp-content\/uploads\/2026\/05\/image-3-300x150.png 300w, https:\/\/memoria-cards.fr\/wp-content\/uploads\/2026\/05\/image-3-768x383.png 768w, https:\/\/memoria-cards.fr\/wp-content\/uploads\/2026\/05\/image-3-1536x767.png 1536w, https:\/\/memoria-cards.fr\/wp-content\/uploads\/2026\/05\/image-3-1320x659.png 1320w, https:\/\/memoria-cards.fr\/wp-content\/uploads\/2026\/05\/image-3.png 1913w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The gains are significant:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Vector quality all the way to output.<\/strong> No resolution decisions until the very last step. The SVG stays sharp at any size, and my print files are genuinely print-ready.<\/li>\n\n\n\n<li><strong>Fine-grained print control under Linux.<\/strong> I drive my color laser printers directly with <code>lp<\/code>, tuning every parameter, page size, duplex mode, color profile, from the command line. No guesswork, no driver dialogs.<\/li>\n\n\n\n<li><strong>Unified color correction.<\/strong> Color adjustments are applied once, consistently, across every card in a run. No more per-file tweaking.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">What I Learned<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The jump from Photoshop to Pillow was about gaining <em>automation<\/em>. The jump from Pillow to SVG was about gaining <em>correctness<\/em>. Both were necessary and I don&rsquo;t think I could have seen the SVG solution without having lived through the Pillow limitations first.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you&rsquo;re building something similar and wondering where to start: design your template in a real vector tool, give your elements meaningful IDs, and let code handle the rest. The separation between <em>design<\/em> and <em>data<\/em> is what makes the whole thing scale.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Making physical trading cards at home sounds simple enough. Design a template, add some art, print it out. But if you want to do it right with consistent quality, scalable production, and clean print output the software side turns out to be a rabbit hole of its own. Here&rsquo;s how my pipeline evolved over two [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-317","page","type-page","status-publish","hentry"],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/memoria-cards.fr\/index.php?rest_route=\/wp\/v2\/pages\/317","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/memoria-cards.fr\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/memoria-cards.fr\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/memoria-cards.fr\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/memoria-cards.fr\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=317"}],"version-history":[{"count":6,"href":"https:\/\/memoria-cards.fr\/index.php?rest_route=\/wp\/v2\/pages\/317\/revisions"}],"predecessor-version":[{"id":415,"href":"https:\/\/memoria-cards.fr\/index.php?rest_route=\/wp\/v2\/pages\/317\/revisions\/415"}],"wp:attachment":[{"href":"https:\/\/memoria-cards.fr\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=317"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}