我搜索了各种各样的“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接受宽输入图像?
答案 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
>
由此我可以通过预览生成一个非常宽(12505×729)的PNG文件。因此,我发现TK Canvas Widget生成的PostScript很难,至少在我的Apple系统上是这样。