Ghostscript正在切断我的ps到png

时间:2017-08-13 10:59:02

标签: python user-interface tkinter ghostscript

关于ghostscript和tkinter的问题:

我制作了一个tkinter程序,我想转换成图像;我希望图像的纸张比例为8.5 x 12;我读过它的2550x3300像素。 这如何转换为画布坐标?现在我选择了一些比率相似的数字,宽度= 1275,身高= 1650 另外,帆布及其尺寸究竟是什么?我认为这是我可以写入的长度,但是我可以将滚动区域设置得比给定的宽度和高度更远。

画布代码的基本思想:

class Application(tk.Frame):
    def __init__(self, master):
        self.master=master

        self.canvas = tk.Canvas(master, width=1275, height=1650, bg='white', highlightthickness=0,
                                scrollregion=(0, 0, 1275, 1650))
        self.hbar = Scrollbar(master, orient=HORIZONTAL)
        self.hbar.pack(side=TOP, fill=X)
        self.hbar.config(command=self.canvas.xview)
        self.vbar = Scrollbar(master, orient=VERTICAL)
        self.vbar.pack(side=RIGHT, fill=Y)
        self.vbar.config(command=self.canvas.yview)

        self.canvas.config(width=1275, height=1650)
        self.canvas.config(xscrollcommand=self.hbar.set, yscrollcommand=self.vbar.set)
        self.canvas.pack(side=LEFT, expand=True, fill=BOTH)


        B1=Button(master,text='add image',command= lambda:self.insert_image())
        B1.pack(side=TOP)

这是我的Ghostscript相关代码:

def _save(self):

    self.canvas.postscript(file="tmp.ps",colormode='color')

    args = [
        "ps2jpg",  
        "-dSAFER","-dBATCH", "-dNOPAUSE",
        "-sDEVICE=png16m",
        "-sOutputFile=./ABC.png",
        "./tmp.ps"

    ]

    ghostscript.Ghostscript(*args)

它似乎在左侧和右侧切割。 然后我添加了参数,如-dFitPage"," -g1275x1650"," -dPSFitPage",甚至" -g2550x3300"而不是" -g1275x1650",但它会产生不同的错误, 我的画布顶部最终位于我保存的图像中间。我想要的是我的画布顶部出现在我的图像顶部。

谢谢。

Image of what my canvas looks like

how it saves

1 个答案:

答案 0 :(得分:0)

好的,首先,您引用的尺寸使用' -g'这是像素数。显然,实际的媒体大小将取决于分辨率。如果我声明尺寸为600x600,分辨率为600 dpi,则分辨率为1英寸×1英寸,如果分辨率为300 dpi,则为2英寸×2英寸。

所以你不能说8.5x12英寸(那应该是标准的媒体尺寸之一?)是2550x3300像素,而且没有说明分辨率。事实上,这甚至都是正确的。如果我认为3300对12英寸长度是正确的,那么它的分辨率为275 dpi。如果我然后计算宽度为2550/275 = 9英寸。

实际上,png16m设备的默认分辨率似乎为72.因此,2550 x 3300像素表示您的介质为35x45英寸。你有滚动条也不足为奇: - )

当然,您的PostScript程序可能会改变分辨率,但由于您还没有提供它,我无法说明。

现在,Postscript坐标系统(默认情况下)在左下角开始,为0,0,在两个方向上延伸,正数上升,右,负数下降走了。是的,它完全可以指定部分或全部绘图操作在媒体之外进行。

你也可以改变坐标系统,但这可能比你想要的更复杂。

在没有看到你的PostScript程序的情况下,我无法真正说出它为什么部分偏离了媒体,这可能就是程序所要求的。

使用FitPage会尝试将所请求的图像适合页面,如果它太大,它会将其缩小(线性,两个方向相同),直到两个尺寸都适合媒体。除非您的介质与所请求的程序形状相同,否则这将导致一个方向的空白区域。然后,最小的尺寸居中。我不记得确切,但我认为如果该程序标记适合媒体,那么它只是它的中心。

所以基本上,你需要让尺寸正确才能开始。假设您对72 dpi输出图像感到满意,并且您的介质真的是8.5x12英寸,那么您可以指定-g612x864。如果渲染的图像不能精确匹配,那么您的程序很可能会从媒体上做出标记,使用的是不同的媒体大小,或“某些东西”。如果没有看到PostScript,就无法说出来。

如果你可以分享一个简单的PostScript文件我可以看一下(我不能使用任何需要我使用tkinter的东西,抱歉)并给你一些更详细的指导。

[编辑]

因此输出实际上是EPS,而不是PostScript程序,我们可以从最初的评论中看到这一点(任何以'%'开头的行是注释):

%!PS-Adobe-3.0 EPSF-3.0
%%Creator: Tk Canvas Widget
%%Title: Window .49823304L
%%CreationDate: Mon Aug 14 23:47:27 2017
%%BoundingBox: -171 85 785 707

%!PS告诉我们它的PostScript程序,-Adobe-3.0告诉我们它符合文档结构约定的3.0版本(一种创建PostScript程序的方法,使它们对非PostScript解释器更具可移植性)和EPSF告诉我们我们实际一个EPS,最后尾随-3.0声明它符合EPS规范的3.0版。

现在,EPS文件无意直接发送到PostScript解释器。它们应该被包含在其他PostScript程序中,并用作一种黑盒子'。当对象是公司徽标不会改变时,或者当您将作品发送给外部机构(例如自由图形艺术家)时,他们可能会将其作为EPS发送给您使用。

EPS符合关于它能够和不能包含的某些规则。 不能做的重要事情之一是设置媒体大小。执行setpagedevice可能会导致设备重置标记的内容,这会丢弃在媒体选择之前所做的任何标记。

此外,EPS在最终页面上绘制时并不知道它的大小。您可以想到在首页上绘制的徽标很大,然后在每页的页脚中绘制得很小。

所以EPS包含的是它标记页面的声明,这是由BoundingBox给出的:

%%BoundingBox: -171 85 785 707

现在您将注意到此EPS的BoundingBox从-179,85开始并延伸到785,707。所以它的宽度是964,高度是792.那些是PostScript5单位,是1/72英寸。所以你的EPS实际上是13.38英寸宽,12英寸高。不仅如此,它距离媒体的左边缘2.48英寸。

这可能解释了为什么您无法获得所需的输出,您可能没有在Ghostscript中正确设置媒体,并且翻译原点以使左边缘不会脱离媒体。

应用程序的工作是将EPS放在其自己的PostScript输出中,以翻译和缩放坐标系统,以便EPS在最终媒体上处于所需的位置和大小。

所以你有一个选择;您可以创建一个PostScript程序,该程序可以适当地设置当前转换矩阵以缩放和定位EPS,然后完整地包含EPS,使用showpage完成实际渲染(EPS文件可能不包括showpage,原因很明显)

或者您可以使用Ghostscript中的-dEPSCrop或EPSFitPage开关(记录为here),这些开关适合页面内容或内容页面。请注意,Fit​​Page开关的精确行为取决于您使用的Ghostscript的确切版本,您还没有提到。当前版本的文档为9.21。

如果您自己创建一个PostScript程序来完成工作,那么您可以完全控制其渲染方式,如果您让Ghostscript执行此操作,那么您可以控制较少但操作简单。你的选择真的。

注意,pastebin突然停止并且没有实际标记,因此它不是有效的PostScript程序。如果你将整个文件放在DropBox或soemthing上,我可能会更具体,但是上面肯定包含了要点。