如何按行和列排列对象并以 .svg 格式导出

How to arrange objects in rows and columns and export in .svg

我是 Python 的新手,我正在尝试访问 Google 的 QuickDraw 数据库并根据用户输入的列和行排列一定数量的图像(矢量线) ,然后以 .svg 文件格式导出。到目前为止,我只设法将每张图片保存为 .gif 格式并显示出来。如何将它们排列成 3x3 网格和 .svg 格式?

这是我目前得到的代码:

from PIL import Image, ImageDraw
from quickdraw.data import QuickDrawData

rows = int(input("How many rows do you want? "))
columns = int(input("How many columns do you want? "))
rows_columns = rows * columns
name_var = 0

for image in range(0,rows_columns):
    
    qd = QuickDrawData()
    duck = qd.get_drawing("duck")
    duck_image = Image.new("RGB", (255,255), color = (255,255,255))
    duck_drawing = ImageDraw.Draw(duck_image)

    for stroke in duck.strokes:

        for coordinate in range(len(stroke)-1):
            x1 = stroke[coordinate][0]
            y1 = stroke[coordinate][1]
            x2 = stroke[coordinate+1][0]
            y2 = stroke[coordinate+1][1]
            duck_drawing.line((x1,y1,x2,y2), fill=(0,0,0), width=2)

    duck_image.show()
    name_var += 1
    duck.image.save(f"my_duck{name_var}.gif")

This is ideally what the outcome should look like 和 .svg 文件格式。

您将需要一个可以输出 SVG 文件的 python 库。

不幸的是,我没有时间提供一个刚刚运行的代码片段的详细答案,但希望我能提供一些指导。

有多个 python 模块可以编写 SVG 文件:svgwrite is one of them (docs, examples).

基于示例片段:

import svgwrite

dwg = svgwrite.Drawing('test.svg', profile='tiny')
dwg.add(dwg.line((0, 0), (10, 0), stroke=svgwrite.rgb(10, 10, 16, '%')))
dwg.add(dwg.text('Test', insert=(0, 0.2), fill='red'))
dwg.save()

您应该可以执行以下操作:

from PIL import Image, ImageDraw
from quickdraw.data import QuickDrawData
import svgwrite

dwg = svgwrite.Drawing('test.svg', profile='tiny')

rows = int(input("How many rows do you want? "))
columns = int(input("How many columns do you want? "))
rows_columns = rows * columns
name_var = 0

for image in range(0,rows_columns):
    
    qd = QuickDrawData()
    duck = qd.get_drawing("duck")
    duck_image = Image.new("RGB", (255,255), color = (255,255,255))
    duck_drawing = ImageDraw.Draw(duck_image)

    for stroke in duck.strokes:

        for coordinate in range(len(stroke)-1):
            x1 = stroke[coordinate][0]
            y1 = stroke[coordinate][1]
            x2 = stroke[coordinate+1][0]
            y2 = stroke[coordinate+1][1]
            duck_drawing.line((x1,y1,x2,y2), fill=(0,0,0), width=2)
            # you many need to offset dwg.line using row/col grid index and drawing size
            dwg.add(dwg.line((x1, y1), (x2, y2), stroke=svgwrite.rgb(10, 10, 16, '%')))

    duck_image.show()
    name_var += 1
    duck.image.save(f"my_duck{name_var}.gif")
# save svg of all ducks (grid)
dwg.save()
    

切记上面的代码没有经过测试,但希望它能说明问题。如果您是该模块的新手,我建议您采用循序渐进的方法:

  1. 编写基本 svg 的基本测试脚本(例如示例片段):确保模块已正确安装并正常工作
  2. 使用 quickdraw 和 svgwrite 绘制一只鸭子的基本脚本
  3. 绘制鸭子网格的脚本

想法是,如果任何步骤失败,debug/fix 隔离会更容易。

我怀疑您可能还需要计算出每只鸭子的 dimensions/bounding 框和 scale/align 到网格的相同大小的矩形,然后偏移每条线的坐标。从理论上讲,您可以将每只鸭子画成一个组,然后简单地使用 SVG 转换每个组,使其对齐为网格(而不是所有鸭子重叠)

此外,您可能会发现 sketch-rnn 很有趣,因为它使用了 quickdraw 数据集。特别是检查 David Ha 的 Sketch-RNN Colab notebook or his sketch-rnn/utils.py 脚本。尽管 QuickDraw 笔划格式与 sketch-rnn 笔划格式略有不同,但仍有很多相似之处,并且上面的 links 包含用于绘制 svg 网格的实用函数。他们需要适应 QuickDraw 的格式。

如果您不受限于 Python 并且对 JavaScript 感到满意,QuickDraw 数据集自述文件已经包含 link 到 d3.js SVG demo