如何使用turtle.py生成非常宽的图像?

时间:2017-04-29 03:01:24

标签: canvas ghostscript turtle-graphics postscript

我搜索了各种各样的“PIL tkinter canvas”。我发现的最接近的是: How to convert a Python tkinter canvas postscript file to an image file readable by the PIL?

turtle.py在可滚动的tkinter画布上创建图像,所以我根据上面的答案编写了一个脚本。

#! /usr/bin/python3

import sys
print(sys.argv[0])
sys.path.append('C:\\Program Files\\gs\\gs9.21\\bin\\') # Where Ghostscript lives
import turtle as t
from PIL import Image  
def line(nPlots=0,x0=0,y0=0,H=6000):
    t.penup()
    t.goto(x0,y0)
    #t.setheading(90)
    t.begin_fill()
    t.pendown()
    print('Forward:',H)
    t.forward(H)
t.screensize(12000,700)
t.color('red','light blue')
t.width(20)
t.tracer(10000)
line()

c=t.getcanvas()
t.update()
c.update()
import io
def savecanvas():
    screen=t.getscreen()
    canvas=screen.getcanvas()
    postscript=canvas.postscript().encode('utf-8')
    im=Image.open(io.BytesIO(postscript))
    im.save('canvas.png')
savecanvas()

这确实会导致屏幕捕获但不是完整的画布捕获。输出文件是所需的12000像素长,但长红色条按屏幕大小裁剪。罪魁祸首似乎是Ghostscript Bounding Box。以下是gs文件的片段:

  

infile:b“%!PS-Adobe-3.0 EPSF-3.0 \ n %%创作者:Tk Canvas   Widget \ n %%标题:Window。!canvas \ n %% CreationDate:Sat Apr 29 10:36:40   2017 \ n %% BoundingBox: -197 188 811 605 \ ...

Ghostscript在PIL EpsImagePlugin.py中设置,从PIL Image模块调用。

以下是代码:

# Build ghostscript command
command = ["gs",
           "-q",                         # quiet mode
           "-g%dx%d" % (12000, 800),     # set output geometry (pixels)
           "-r%fx%f" % (96,96),          # set input DPI (dots per inch)
           "-dNOPAUSE",                  # don't pause between pages,
           "-dSAFER",                    # safe mode
           "-sDEVICE=ppmraw",            # ppm driver
           "-sOutputFile=%s" % outfile,  # output file
           "-c", "%d %d translate" % (-300,-375),
                                         # adjust for image origin
           "-f", infile,                 # input file

我试图强制bbox没有成功。我怀疑我需要一些额外的gs命令行选项。

有谁知道如何强制Ghostscript接受宽输入图像?

2 个答案:

答案 0 :(得分:0)

这不是 Ghostscript BoundingBox,它是PostScript程序声明的Bounding Box。显然由'TK Canvas Widget'制作,所以如果它的错误,罪魁祸首不是Ghostscript。

请注意,Ghostscript会完全忽略它,因为它的注释(以'%'开头)除非你设置-dEPSCrop,否则你没有。由于它声称是EPS文件(此评论:“%!PS-Adobe-3.0 EPSF-3.0”)尝试使用-dEPSCrop

我还会获取EPS文件并尝试直接从EPS文件的命令行运行Ghostscript。你在命令行中有很多开关,我怀疑这些开关只会让事情变得复杂。

首先我会删除-g开关,因为这会设置固定大小的媒体(以像素为单位),如果你想要一个可变的媒体大小,你不想修复它,除非你也设置-dPSFitPage,它会将请求的媒体(由BoundingBox给出,如果您使用-dEPSCrop)缩放到-g给出的固定页面大小。最初,至少我会放弃它,它只是阻碍了它。

然后你可能还想放弃-c "..." -f,因为这会改变媒体上的内容。

如果你做了所有这些,我希望Ghostscript以你要求的分辨率为你生成一个ppmraw文件,并包含整个内容。当然,这并不能证明它的“完整”。如果不是,那么您可能需要提供一个示例来查看。

答案 1 :(得分:0)

我将对@KenS给出一个矛盾的答案,并说TK Canvas Widget生成的PostScript看起来很好。我使用以下简化代码来转储PostScript:

from turtle import Turtle, Screen

def line(turtle, H=6000):
    turtle.penup()
    turtle.begin_fill()
    turtle.pendown()
    turtle.forward(H)

def savecanvas(screen):
    canvas = screen.getcanvas()
    canvas.postscript(file="canvas.eps")

screen = Screen()
screen.setup(12000, 700)

yertle = Turtle()
yertle.pencolor('red')
yertle.width(20)

line(yertle)

savecanvas(screen)

screen.bye()

然后我通过grep检查它并在Mac上预览:

> grep BoundingBox canvas.eps
%%BoundingBox: -5696 46 6309 746
> 

enter image description here

enter image description here

由此我可以通过预览生成一个非常宽(12505×729)的PNG文件。因此,我发现TK Canvas Widget生成的PostScript很难,至少在我的Apple系统上是这样。