寻求可实现类似Inkscape嵌入图片至SVG功能的Python库——NFT随机生成项目技术问询
Hey there! Perfect question for your NFT generator project—let’s break down the best Python tools to automate embedding JPG/PNG images into SVGs (just like Inkscape’s Embed Images extension) so you can skip manual steps and build your workflow end-to-end.
First, a quick recap of how embedding works: instead of linking to external image files, we convert the image data into a base64-encoded string and use a data URI directly in the SVG. This is exactly what Inkscape does behind the scenes, and it’s totally achievable with Python.
Top Python Libraries for the Job
1. svgwrite (For Creating SVGs from Scratch)
If you’re building your SVG files from the ground up, svgwrite is a straightforward library that lets you define SVG elements and embed images using base64 data. Pair it with Pillow (PIL) to handle image reading and encoding smoothly.
Here’s a working example:
import svgwrite import base64 from PIL import Image # Helper function to convert images to base64 strings def image_to_base64(image_path): with open(image_path, "rb") as img_file: return base64.b64encode(img_file.read()).decode("utf-8") # Create a new SVG document dwg = svgwrite.Drawing("nft_template.svg", size=("600px", "600px")) # Embed a background JPG bg_data = image_to_base64("background.jpg") dwg.add(dwg.image( f"data:image/jpeg;base64,{bg_data}", insert=(0, 0), size=("600px", "600px") )) # Embed a PNG layer layer_data = image_to_base64("nft_layer_1.png") dwg.add(dwg.image( f"data:image/png;base64,{layer_data}", insert=(50, 50), size=("500px", "500px") )) # Save the final embedded SVG dwg.save()
2. lxml (For Modifying Existing SVGs)
If you already have SVG templates and just need to inject embedded images into them, lxml is ideal for parsing and editing SVG XML. It handles namespaces correctly (critical for SVG’s image elements) and lets you insert images anywhere in the SVG hierarchy.
Example code to embed an image into a pre-made SVG:
from lxml import etree import base64 def embed_image_in_svg(svg_path, image_path, x=0, y=0, width=300, height=300): # Parse the existing SVG tree = etree.parse(svg_path) root = tree.getroot() # SVG requires proper namespace handling ns = { "svg": "http://www.w3.org/2000/svg", "xlink": "http://www.w3.org/1999/xlink" } # Encode the image to base64 with open(image_path, "rb") as img_file: img_base64 = base64.b64encode(img_file.read()).decode("utf-8") # Determine the correct MIME type for the image if image_path.lower().endswith(".png"): mime_type = "image/png" elif image_path.lower().endswith((".jpg", ".jpeg")): mime_type = "image/jpeg" else: raise ValueError("Only PNG/JPG images are supported") # Create the <image> element with embedded data image_element = etree.SubElement( root, "{http://www.w3.org/2000/svg}image", x=str(x), y=str(y), width=str(width), height=str(height), **{"{http://www.w3.org/1999/xlink}href": f"data:{mime_type};base64,{img_base64}"} ) # Save the modified SVG tree.write("embedded_nft.svg", encoding="utf-8", xml_declaration=True) # Usage: Embed a layer into your template embed_image_in_svg("nft_base.svg", "rare_layer.png", x=100, y=100, width=400, height=400)
3. Bonus: Pillow (For Image Preprocessing)
While not an SVG-specific library, Pillow is essential for resizing, cropping, or adjusting images before embedding it into your SVG. This is super useful for standardizing NFT layer dimensions.
Integrating with GTK3
Once you have your embedded SVG, you can use GTK3’s librsvg bindings (via python-rsvg or gi.repository.Rsvg) to render the SVG directly to a PNG. Here’s a quick snippet to tie it all together:
from gi.repository import Gtk, Rsvg, GdkPixbuf def svg_to_png(svg_path, output_png_path): # Load the embedded SVG handle = Rsvg.Handle.new_from_file(svg_path) dimensions = handle.get_dimensions() # Create a pixbuf to render the SVG pixbuf = GdkPixbuf.Pixbuf.new( GdkPixbuf.Colorspace.RGB, False, 8, dimensions.width, dimensions.height ) pixbuf.fill(0xFFFFFF) # White background # Render the SVG to the pixbuf cr = Gdk.cairo_create(pixbuf) handle.render_cairo(cr) # Save as PNG pixbuf.savev(output_png_path, "png", [], []) # Usage: Convert your embedded SVG to PNG for the NFT svg_to_png("embedded_nft.svg", "final_nft.png")
All these methods produce SVGs with fully embedded images (no external links), just like Inkscape’s extension does. They fit perfectly into your Python + GTK3 workflow for generating randomized NFTs.
内容的提问来源于stack exchange,提问作者Ekky Armandi

