# Sketch - A Python-based interactive drawing program # Copyright (C) 1999, 2000 by Bernhard Herzog # # 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 two commands to the Script menu: # # Export Raster Renders the drawing on a white background # # Export Raster Alpha Renders with anti-aliasing and alpha channel, so # that those parts of the page that are not # covered are transparent. # # 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. # # Both scripts render the drawing at 72ppi and set the image size to the # dimensions of the page in pt. These settings are not appropriate for # all purposes so you might want to change them or hack the script to # ask for them. import os, tempfile import PIL.Image, PIL.ImageChops import Sketch.Scripting from Sketch import PostScriptDevice 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 = "-dGraphicsAlphaBits=%d" % 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() os.system(gs_cmd) image = PIL.Image.open(temp) image.load() return image finally: try: os.unlink(temp) except: pass def export_raster(context, filename, resolution, use_bbox): # parameters: # # filename: filename of the raster image file # gsdevice: ghostscript device name for the raster format, e.g. ppmraw # resolution: pixel per inch # 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) finally: os.unlink(temp) image.save(filename) 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): ps = make_ps(context.document) width, height = context.document.PageSize() width = round(width * resolution / 72.0) height = round(height * resolution / 72.0) rgb = render_ps(ps, resolution, width, height, antialias = 2) alpha = render_ps(ps, resolution, width, height, antialias = 2, prolog = alpha_prolog, gsdevice = 'pgmraw') alpha = PIL.ImageChops.invert(alpha) rgb = rgb.convert('RGBA') rgb.putalpha(alpha) rgb.save(filename) filetypes = (('Portable Pixmap', '.ppm'), ('Portable Graymap', '.pgm'), ('Jpeg', '.jpg'), ('Portable Network Graphics', '.png')) def export_raster_interactive(context, alpha = 0, use_bbox = 0): # popup a filedialog and export the document doc = context.document # construct the tk filetypes list extensions = {} for text, ext in filetypes: extensions[ext] = 1 # determine a default filename basename = os.path.splitext(doc.meta.filename)[0] if alpha: default_ext = '.png' else: default_ext = '.ppm' 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, 72, use_bbox) else: export_raster(context, filename, 72, 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_interactive, script_type = Sketch.Scripting.AdvancedScript) Sketch.Scripting.AddFunction('export_raster', 'Export Raster Alpha', export_raster_interactive, args = (1,), script_type = Sketch.Scripting.AdvancedScript)