Created
May 24, 2011 16:38
-
-
Save larscwallin/989080 to your computer and use it in GitHub Desktop.
My fine Inkscape extensions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<inkscape-extension> | |
<_name>Create Sketch Layer</_name> | |
<id>com.larscwallin.create_sketch_layer</id> | |
<dependency type="executable" location="extensions">create_sketch_layer.py</dependency> | |
<dependency type="executable" location="extensions">inkex.py</dependency> | |
<!-- <param name="what" type="string" _gui-text="What?"></param> --> | |
<param name="where" type="string" _gui-text="Sketch save location"></param> | |
<param name="sketch_name" type="string" _gui-text="Sketch name"></param> | |
<param name="remove_border" type="boolean" _gui-text="Remove element border?"></param> | |
<param name="replace_source" type="boolean" _gui-text="Replace original element?"></param> | |
<param name="sketch_editor" type="string" _gui-text="Sketch editor"></param> | |
<effect> | |
<object-type>all</object-type> | |
<effects-menu> | |
<submenu _name="Sketch"/> | |
</effects-menu> | |
</effect> | |
<script> | |
<command reldir="extensions" interpreter="python">larscwallin.inx.create-sketch-layer.py</command> | |
</script> | |
</inkscape-extension> | |
<!-- | |
Contents | |
[hide] | |
1 boolean | |
2 int | |
3 float | |
4 string | |
5 description | |
6 enum | |
7 notebook | |
8 optiongroup | |
9 color | |
boolean | |
Gives a checkbox in the dialog; the default value may be "true" or "1", "false" or "0". | |
int | |
To get an integer; sort of textbox in the dialog. | |
float | |
To get an float number; sort of textbox in the dialog. | |
string | |
To get an character string; textbox in the dialog. | |
description | |
To show some text in the dialog. | |
enum | |
List of choices; the different choices are given by <item> elements. | |
notebook | |
To have different pages in the dialog; the other parameters are given inside <page> elements. | |
optiongroup | |
List of choices with rounded checkboxes; the different choices are given by <option> elements. | |
color | |
?? | |
Retrieved from "http://wiki.inkscape.org/wiki/index.php/INX_Parameters" | |
--> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
""" | |
Copyright (C) 2012 Lars C Wallin | |
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: | |
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. | |
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
Version 0.2 121111 | |
This script was written by Lars Wallin to make bitmap sketching easy. | |
It simply, | |
1. takes the currently selected element (a white/transparent surface seems a logical choice), | |
2. exports it to png | |
3. inserts it as a linked image element into a new layer in the current Inkscape drawing | |
4. opens the png in your editor of choice | |
5. lets you sketch away on the bitmap | |
6. waits for the sketching app to close | |
7. updates the linked bitmap in Inkscape | |
After this i use the bitmap to auto, or, manualy trace . | |
Have fun :) | |
PS. | |
Written on Ubuntu. If you run Windows make sure that you change the save path for the bitmap | |
as it defaults the Linux:y /home/ | |
DS. | |
""" | |
import inkex | |
import sys, os, commands,subprocess | |
import os.path | |
import string | |
from time import time | |
from xml.dom.minidom import Document | |
from xml.dom.minidom import DocumentType | |
# This line is only needed if you don't put the script directly into | |
# the installation directory | |
# sys.path.append('/usr/share/inkscape/extensions') | |
# The simplestyle module provides functions for style parsing. | |
from simplestyle import * | |
# Effect main class | |
class CreateSketchLayer(inkex.Effect): | |
parserProcessHandle = None | |
saveLocation = "" | |
where = "" | |
what = "" | |
sketch_name = "" | |
remove_border = False | |
replace_source = False | |
sketch_editor = "" | |
svg_file = "" | |
renderHistory = [] | |
rectangle_id = "" | |
def __init__(self): | |
""" | |
Constructor. | |
Defines the "--what" option of a script. | |
""" | |
# Call the base class constructor. | |
inkex.Effect.__init__(self) | |
# The OptionParser stuff below are Inkscape specific code which sets up the dialog for the extension GUI. | |
# The current options are just lab stuff and should be substituted with something more usefull. | |
self.OptionParser.add_option('--where', action = 'store', | |
type = 'string', dest = 'where', default = '', | |
help = 'Where to save?') | |
self.OptionParser.add_option('--sketch_name', action = 'store', | |
type = 'string', dest = 'sketch_name', default = 'New Sketch', | |
help = 'Sketch name') | |
self.OptionParser.add_option('--remove_border', action = 'store', | |
type = 'inkbool', dest = 'remove_border', default = False, | |
help = 'Remove canvas border?') | |
self.OptionParser.add_option('--replace_source', action = 'store', | |
type = 'inkbool', dest = 'replace_source', default = False, | |
help = 'Replace source element with sketch input?') | |
self.OptionParser.add_option('--sketch_editor', action = 'store', | |
type = 'string', dest = 'sketch_editor', default = '', | |
help = 'Application name for sketching. This value will be used at the command line, so please use the key used for starting the app in this context.') | |
# exportImage takes as argument the current svg element id. This is then used to select which element the Inkscape exe should export. | |
def exportImage(self,id): | |
# The easiest way to name rendered elements is by using their id since we can trust that this is always unique. | |
filename = os.path.join(self.where, id+'.png') | |
#self.debugPrint(filename) | |
# Inkscape has many really useful cmd line arguments which can be used to query for data, and render bitmaps. | |
# Please not that Inkscape supports shell execution and should really be started as such at the beginning of parsing. | |
# The shell spawning stuff is commented out at the bottom of this script. | |
# The current command will start/close a new instance of the app for every element parsed. | |
command = 'inkscape --without-gui --export-id-only --export-id %s --export-png %s %s' % (id, filename, self.svg_file) | |
#self.debugPrint(command) | |
processHandle = subprocess.Popen(command, | |
shell=True, | |
stdout=subprocess.PIPE) | |
# Inkscape is gracious enough to return some metadata regarding the exported bitmap. | |
stdout_value = processHandle.communicate()[0] | |
#self.debugPrint(stdout_value) | |
return (filename) | |
def openImage(self,filename,sketch_editor): | |
#self.debugPrint("opening "+filename) | |
if(sketch_editor!=""): | |
command = '"%s" "%s"' % (sketch_editor,filename) | |
else: | |
command = '"%s"' % (filename) | |
processHandle = subprocess.Popen(command, | |
shell=True, | |
stdout=subprocess.PIPE) | |
#self.debugPrint(command) | |
stdout_value = processHandle.communicate()[0] | |
#self.debugPrint('editor returned '+command) | |
def effect(self): | |
""" | |
Effect behaviour. | |
Overrides base class method | |
""" | |
self.svg_file = self.args[-1] | |
# Get script's "--where" option value. | |
self.where = self.options.where | |
if(self.where==''): | |
self.where = os.path.dirname(self.svg_file) | |
#self.debugPrint(self.replace_source) | |
if(self.where==''): sys.exit() | |
self.sketch_name = self.options.sketch_name | |
self.sketch_editor = self.options.sketch_editor | |
self.sketch_editor = self.sketch_editor if self.sketch_editor != '' else '' | |
sketch_file_path = '' | |
sketch_canvas = '' | |
sketch_canvas_x = '' | |
sketch_canvas_y = '' | |
sketch_canvas_height = '' | |
sketch_canvas_width = '' | |
sketch_canvas_id = '' | |
svg = self.document.xpath('//svg:svg',namespaces=inkex.NSS)[0] | |
layer_width = inkex.unittouu(svg.get('width')) | |
layer_height = inkex.unittouu(svg.get('height')) | |
# Create layer element | |
layer = inkex.etree.SubElement(svg, 'g') | |
layer.set(inkex.addNS('label', 'inkscape'), '%s' % (self.sketch_name)) | |
layer.set(inkex.addNS('groupmode', 'inkscape'), 'layer') | |
self.getselected() | |
if(self.selected.__len__() > 0): | |
sketch_canvas = self.selected.values() | |
sketch_canvas = sketch_canvas[0] | |
if(sketch_canvas!=''): | |
# Get the position of the sketch element | |
sketch_canvas_id = sketch_canvas.get('id') | |
sketch_canvas_x = sketch_canvas.get('x') | |
sketch_canvas_y = sketch_canvas.get('y') | |
sketch_canvas_height = sketch_canvas.get('height') | |
sketch_canvas_width = sketch_canvas.get('width') | |
# Export the selected element as sketch bitmap | |
sketch_bitmap_path = self.exportImage(sketch_canvas_id) | |
if(sketch_bitmap_path != ''): | |
# Create and insert a new image element for the sketch bitmap | |
sketch_bitmap_element = inkex.etree.SubElement(layer,'image') | |
# Set rectangle position to top/left width/height. | |
sketch_bitmap_element.set('x', str(sketch_canvas_x)) | |
sketch_bitmap_element.set('y', str(sketch_canvas_y)) | |
sketch_bitmap_element.set('width', str(sketch_canvas_width)) | |
sketch_bitmap_element.set('height', str(sketch_canvas_height)) | |
# Set basic style attributes | |
sketch_bitmap_element.set(inkex.addNS('href', 'xlink'), str(sketch_bitmap_path)) | |
# Connect elements together. | |
layer.append(sketch_bitmap_element) | |
try: | |
self.openImage(sketch_bitmap_path,self.sketch_editor) | |
except: | |
self.debugPrint('Gimp error') | |
if(self.replace_source): | |
sketch_canvas.getparent().remove(sketch_canvas) | |
else: | |
self.debugPrint('sketch_bitmap_path was empty') | |
def debugPrint(self,textStr): | |
debugLayer = self.document.xpath('//svg:svg/svg:g',namespaces=inkex.NSS)[0] | |
# Create text element | |
text = inkex.etree.Element(inkex.addNS('text','svg')) | |
text.text = str(textStr) | |
# Set text position to center of document. | |
text.set('x', str(300 / 2)) | |
text.set('y', str(300 / 2)) | |
# Center text horizontally with CSS style. | |
style = {'text-align' : 'center', 'text-anchor': 'middle'} | |
text.set('style', formatStyle(style)) | |
# Connect elements together. | |
debugLayer.append(text) | |
# Create effect instance and apply it. | |
effect = CreateSketchLayer() | |
effect.affect() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<inkscape-extension> | |
<_name>Elements to Layers</_name> | |
<id>larscwallin.inx.elements-to-layers</id> | |
<dependency type="executable" location="extensions">elements_to_layers.py</dependency> | |
<dependency type="executable" location="extensions">inkex.py</dependency> | |
<!-- | |
self.prefix = self.options.prefix | |
self.suffix = self.options.suffix | |
self.keep_source_element = self.options.keep_source_element | |
self.name_using_element_id = self.options.name_using_element_id | |
self.center_element_on_layer = self.options.center_element_on_layer | |
--> | |
<param name="prefix" type="string" _gui-text="Layer prefix"></param> | |
<param name="suffix" type="string" _gui-text="Layer suffix"></param> | |
<param name="delete_source_element" type="boolean" _gui-text="Delete original elements?"></param> | |
<param name="center_element_on_layer" type="boolean" _gui-text="Center elements on canvas?"></param> | |
<param name="name_using_element_id" type="boolean" _gui-text="Name layers after element id?"></param> | |
<effect> | |
<object-type>all</object-type> | |
<effects-menu> | |
<submenu _name="Generate from Path"/> | |
</effects-menu> | |
</effect> | |
<script> | |
<command reldir="extensions" interpreter="python">larscwallin.inx.elements-to-layers.py</command> | |
</script> | |
</inkscape-extension> | |
<!-- | |
Contents | |
[hide] | |
1 boolean | |
2 int | |
3 float | |
4 string | |
5 description | |
6 enum | |
7 notebook | |
8 optiongroup | |
9 color | |
boolean | |
Gives a checkbox in the dialog; the default value may be "true" or "1", "false" or "0". | |
int | |
To get an integer; sort of textbox in the dialog. | |
float | |
To get an float number; sort of textbox in the dialog. | |
string | |
To get an character string; textbox in the dialog. | |
description | |
To show some text in the dialog. | |
enum | |
List of choices; the different choices are given by <item> elements. | |
notebook | |
To have different pages in the dialog; the other parameters are given inside <page> elements. | |
optiongroup | |
List of choices with rounded checkboxes; the different choices are given by <option> elements. | |
color | |
?? | |
Retrieved from "http://wiki.inkscape.org/wiki/index.php/INX_Parameters" | |
--> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
""" | |
Copyright (C) 2012 Lars C Wallin | |
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: | |
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. | |
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
""" | |
import inkex | |
import simpletransform | |
import simplepath | |
import sys, os, commands,subprocess | |
import os.path | |
import string | |
from copy import deepcopy | |
from time import time | |
from xml.dom.minidom import Document | |
from xml.dom.minidom import DocumentType | |
# This line is only needed if you don't put the script directly into | |
# the installation directory | |
# sys.path.append('/usr/share/inkscape/extensions') | |
# The simplestyle module provides functions for style parsing. | |
from simplestyle import * | |
# Effect main class | |
class ElementToLayers(inkex.Effect): | |
parserProcessHandle = None | |
renderHistory = [] | |
svg_doc = None | |
svg_doc_width = '' | |
svg_doc_height = '' | |
svg_file = '' | |
prefix = '' | |
suffix = '' | |
delete_source_element = False | |
name_using_element_id = True | |
center_element_on_layer = True | |
def __init__(self): | |
""" | |
Constructor. | |
""" | |
# Call the base class constructor. | |
inkex.Effect.__init__(self) | |
# The OptionParser stuff below are Inkscape specific code which sets up the dialog for the extension GUI. | |
# The current options are just lab stuff and should be substituted with something more usefull. | |
# Define string option "--what" with "-w" shortcut. | |
# self.prefix = self.options.prefix | |
# self.suffix = self.options.suffix | |
# self.delete_source_element = self.options.delete_source_element | |
# self.name_using_element_id = self.options.name_using_element_id | |
# self.center_element_on_layer = self.options.center_element_on_layer | |
self.OptionParser.add_option('--prefix', action = 'store', | |
type = 'string', dest = 'prefix', default = '', | |
help = 'Prefix to add to generated layers') | |
self.OptionParser.add_option('--suffix', action = 'store', | |
type = 'string', dest = 'suffix', default = '', | |
help = 'Suffix to add to generated layers') | |
self.OptionParser.add_option('--delete_source_element', action = 'store', | |
type = 'inkbool', dest = 'delete_source_element', default = False, | |
help = 'Delete source elements?') | |
self.OptionParser.add_option('--name_using_element_id', action = 'store', | |
type = 'inkbool', dest = 'name_using_element_id', default = True, | |
help = 'Name generated layers using the id of the elements?') | |
self.OptionParser.add_option('--center_element_on_layer', action = 'store', | |
type = 'inkbool', dest = 'center_element_on_layer', default = True, | |
help = 'Center element on layer?') | |
def effect(self): | |
""" | |
Effect behaviour. | |
Overrides base class method | |
""" | |
self.svg_file = self.args[-1] | |
self.prefix = self.options.prefix | |
self.suffix = self.options.suffix | |
self.delete_source_element = self.options.delete_source_element | |
self.name_using_element_id = self.options.name_using_element_id | |
self.center_element_on_layer = self.options.center_element_on_layer | |
self.svg_doc = self.document.xpath('//svg:svg',namespaces=inkex.NSS)[0] | |
self.svg_doc_width = inkex.unittouu(self.svg_doc.get('width')) | |
self.svg_doc_height = inkex.unittouu(self.svg_doc.get('height')) | |
self.getselected() | |
if(self.selected.__len__() > 0): | |
# Iterate through all selected elements | |
for element in self.selected.values(): | |
self.CreateElementLayer(element) | |
def CreateElementLayer(self,element): | |
layer = '' | |
layer_id = '' | |
element_x = '' | |
element_copy = '' | |
element_y = '' | |
element_height = '' | |
element_width = '' | |
element_id = '' | |
# Got a valid element? | |
if(element!=''): | |
# Get the meta data of the current element | |
element_id = element.get('id') | |
element_x = element.get('x') | |
element_y = element.get('y') | |
element_height = element.get('height') | |
element_width = element.get('width') | |
transformation = 'translate(0,0)' | |
transform = simpletransform.parseTransform(transformation) | |
# Create layer element | |
layer = inkex.etree.SubElement(self.svg_doc, 'g') | |
layer.set(inkex.addNS('groupmode', 'inkscape'), 'layer') | |
layer_id = layer.get('id'); | |
# Should we name the layer after the current element id? | |
if(self.name_using_element_id): | |
layer.set(inkex.addNS('label', 'inkscape'), '%s%s%s' % (self.prefix,element_id,self.suffix)) | |
else: | |
layer.set(inkex.addNS('label', 'inkscape'), '%s%s%s' % (self.prefix,layer_id,self.suffix)) | |
# Clone source element | |
element_copy = deepcopy(element) | |
# Center on svg canvas | |
#if(self.center_element_on_layer == True): | |
#simplepath.translatePath(element_copy, 0, 0) | |
#element.set('x', str( (self.svg_doc_width - element_width) / 2 )) | |
#element.set('y', str( (self.svg_doc_height - element_height) / 2 )) | |
# Append to new layer | |
layer.append(element_copy) | |
# Delete source element? | |
if(self.delete_source_element == True): | |
element.getparent().remove(element) | |
def groupElement(self,element): | |
if(element): | |
parent = element.getparent() | |
# Create layer element | |
group = inkex.etree.SubElement(parent, 'g') | |
group.append(element) | |
def ungroupElements(self,group): | |
if(group): | |
# Create layer element | |
parent = group.getparent() | |
elements = group.getChildren() | |
for element in elements: | |
parent.append(element) | |
def parseElement(self,node): | |
element_metadata = "" | |
id = node.get('id') | |
# Do actual export | |
element_metadata = self.exportImage(id,'svg') | |
element_metadata = element_metadata.split(';') | |
element_metadata[3] = element_metadata[3].split(':') | |
# Assign the element_metadata values to an elementData struct which we later can query for element data. This will be used for rendering of content documents. | |
elementData = { | |
'id':element_metadata[0], | |
'parent_id':element_metadata[1], | |
'background': element_metadata[2], | |
'area':{ | |
'x':element_metadata[3][0], | |
'y':element_metadata[3][1], | |
'rel_x':element_metadata[3][2], | |
'rel_y':element_metadata[3][3] | |
}, | |
'width':element_metadata[4], | |
'height':element_metadata[5], | |
'path':element_metadata[6] | |
} | |
# Here we simply add the new struct to the renderHistory array. | |
#self.renderHistory.append(elementData) | |
# And just for debug sake write some stuff back to the document. | |
#self.debugLogger(self.renderHistory[0]['id']) | |
# Create effect instance and apply it. | |
effect = ElementToLayers() | |
effect.affect() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment