# Sketch - A Python-based interactive drawing program
# export_raster script
# Copyright (C) 1999, 2000, 2002, 2003, 2004 by Bernhard Herzog
# 6.12.2000 improved by Bernhard Reiter with Help form Bernhard
# (used create_star.py by Tamito KAJIYAMA as an example to
# build the dialog)
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
# Export Sketch drawings as raster images using ghostscript to render
# them
#
# This script adds the following to the Script menu:
#
# Export Raster Renders the drawing on a white background
#
# You can add more with fixed parameters, if you need them frequently
# see the comments below, one example is enabled.
#
# Both commands prompt for a filename. The output file format is
# determined by the filename extension and should be something your PIL
# installation can handle. For the alpha version this should be PNG or
# some other format that can handle an alpha channel.
#
import sys
import os, tempfile
import PIL.Image, PIL.ImageChops
import Sketch.Scripting
from Sketch import _,PostScriptDevice
# for parameter dialogs
from Sketch.UI.sketchdlg import SKModal
from Tkinter import *
class CreateRasterParametersDlg(SKModal):
"Create Tk Dialog to ask for raster parameters."
title = _("Choose Raster Parameters")
def build_dlg(self):
self.var_ppi = IntVar(self.top)
self.var_ppi.set(72)
label = Label(self.top, text=_("ppi"))
label.grid(column=0, row=0, sticky=E)
entry = Entry(self.top, width=15, textvariable=self.var_ppi)
entry.grid(column=1, row=0)
self.var_alpha = BooleanVar(self.top)
self.var_alpha.set(1)
label = Label(self.top, text=_("w. Transparency"))
label.grid(column=0, row=1, sticky=E)
entry = Checkbutton(self.top, variable=self.var_alpha)
entry.grid(column=1, row=1)
self.var_use_bbox = BooleanVar(self.top)
self.var_use_bbox.set(0)
label = Label(self.top, text=_("use BB information"))
label.grid(column=0, row=2, sticky=E)
entry = Checkbutton(self.top, variable=self.var_use_bbox)
entry.grid(column=1, row=2)
button = Button(self.top, text=_("OK"), command=self.ok)
button.grid(column=0, row=3, sticky=W)
button = Button(self.top, text=_("Cancel"), command=self.cancel)
button.grid(column=1, row=3, sticky=E)
def ok(self):
self.close_dlg((self.var_ppi.get(),
self.var_alpha.get(),self.var_use_bbox.get()))
def export_raster_more_interactive(context, alpha = 0, use_bbox = 0,
render_ppi=72):
"Get Parameter per dialog and run export_raster_interactive()"
parms = CreateRasterParametersDlg(context.application.root).RunDialog()
if parms is None:
return
else:
render_ppi=parms[0]
alpha=parms[1]
use_bbox=parms[2]
return export_raster_interactive(context,alpha,use_bbox,render_ppi)
def make_ps(document):
file = tempfile.mktemp('.ps')
device = PostScriptDevice(file, as_eps = 0, document = document)
document.Draw(device)
device.Close()
return file
def render_ps(filename, resolution, width, height, orig_x = 0, orig_y = 0,
prolog = '', antialias = '', gsdevice = 'ppmraw'):
if prolog:
prolog = '-c ' + '"' + prolog + '"'
if antialias:
antialias = ("-dTextAlphaBits=%d -dGraphicsAlphaBits=%d"
% (antialias, antialias))
else:
antialias = ""
orig_x = -orig_x
orig_y = -orig_y
temp = tempfile.mktemp()
try:
gs_cmd = ('gs -dNOPAUSE -g%(width)dx%(height)d -r%(resolution)d '
'-sOutputFile=%(temp)s %(antialias)s '
'-sDEVICE=%(gsdevice)s -q %(prolog)s '
'-c %(orig_x)f %(orig_y)f translate '
'-f%(filename)s -c quit')
gs_cmd = gs_cmd % locals()
retval = os.system(gs_cmd)
if retval:
sys.stderr.write("skencil:export_raster: executing %s failed"
" with exit code %x\n" % (repr(gs_cmd), retval))
raise IOError("Error running ghostscript."
" Perhaps it's not installed.")
image = PIL.Image.open(temp)
image.load()
return image
finally:
try:
os.unlink(temp)
except:
pass
def export_raster(context, filename, resolution, use_bbox, format = None,
antialias = None):
# instead of the page size one could also use the bounding box
# (returned by the BoundingRect method).
if use_bbox:
left, bottom, right, top = context.document.BoundingRect()
width = right - left
height = top - bottom
x = left; y = bottom
else:
width, height = context.document.PageSize()
x = y = 0
width = round(width * resolution / 72.0)
height = round(height * resolution / 72.0)
temp = make_ps(context.document)
try:
image = render_ps(temp, resolution, width, height,
orig_x = x, orig_y = y, antialias = antialias)
finally:
os.unlink(temp)
image.save(filename, format = format)
alpha_prolog = "/setrgbcolor {pop pop pop 0 0 0 setrgbcolor} bind def \
/setgray { pop 0 setgray} bind def \
/setcmykcolor { pop pop pop pop 0 0 0 1.0 setcmykcolor} bind def "
def export_alpha(context, filename, resolution, use_bbox = 0):
if use_bbox:
left, bottom, right, top = context.document.BoundingRect()
width = right - left
height = top - bottom
x = left; y = bottom
else:
width, height = context.document.PageSize()
x = y = 0
ps = make_ps(context.document)
width = round(width * resolution / 72.0)
height = round(height * resolution / 72.0)
rgb = render_ps(ps, resolution, width, height,
orig_x = x, orig_y = y, antialias = 2)
alpha = render_ps(ps, resolution, width, height,
orig_x = x, orig_y = y, antialias = 2,
prolog = alpha_prolog, gsdevice = 'pgmraw')
alpha = PIL.ImageChops.invert(alpha)
rgb = rgb.convert('RGBA')
rgb.putalpha(alpha)
rgb.save(filename)
filelist = [(_("Portable Pixmap"), '.ppm'),
(_("Portable Graymap"), '.pgm'),
(_("Jpeg"), '.jpg'),
(_("Portable Network Graphics"), '.png')]
def export_raster_interactive(context, alpha = 0, use_bbox = 0, render_ppi=72):
# popup a filedialog and export the document
doc = context.document
# construct the tk filetypes list
extensions = {}
for text, ext in filelist:
extensions[ext] = 1
# determine a default filename
basename = os.path.splitext(doc.meta.filename)[0]
if alpha:
default_ext = '.png'
# shift png up in filetypes so it is displayed accordingly
filetypes=tuple(filelist[-1:]+filelist[1:-1])
else:
default_ext = '.ppm'
filetypes=tuple(filelist)
filename = context.application.GetSaveFilename(
title = _("Export Raster"),
filetypes = filetypes,
initialdir = doc.meta.directory,
initialfile = basename + default_ext)
if filename:
ext = os.path.splitext(filename)[1]
if extensions.has_key(ext):
if alpha:
export_alpha(context, filename, render_ppi, use_bbox)
else:
export_raster(context, filename, render_ppi, use_bbox)
else:
message = _("unknown extension %s") % ext
context.application.MessageBox(title = _("Export Raster"),
message = message)
Sketch.Scripting.AddFunction('export_raster', _("Export Raster"),
export_raster_more_interactive,
script_type = Sketch.Scripting.AdvancedScript)
#Sketch.Scripting.AddFunction('export_raster', 'Export Raster Alpha (Default)',
# export_raster_interactive, args = (1,0),
# script_type = Sketch.Scripting.AdvancedScript)
Sketch.Scripting.AddFunction('export_raster',
_("Export Raster Alpha (100ppi)"),
export_raster_interactive, args = (1,0,100),
script_type = Sketch.Scripting.AdvancedScript)
#Sketch.Scripting.AddFunction('export_raster', 'Export Raster Alpha (120ppi)',
# export_raster_interactive, args = (1,0,120),
# script_type = Sketch.Scripting.AdvancedScript)
|