diff --git a/coordinates_extension.inx b/coordinates_extension.inx
index 638d042..6964b26 100644
--- a/coordinates_extension.inx
+++ b/coordinates_extension.inx
@@ -3,6 +3,7 @@
Georeference
org.smolnet.code.inkscape-coordinates
Geo reference an image
+
diff --git a/coordinates_extension.py b/coordinates_extension.py
index 4745a0b..2cef4f5 100755
--- a/coordinates_extension.py
+++ b/coordinates_extension.py
@@ -15,59 +15,221 @@
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # noqa: E501
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA.
#
"""
Description of this extension
"""
-import inkex
-import inkex.gui
import gi
+import math
+import io
+import inkex
+import base64
+from inkex import Image as IImage
+from PIL import Image
gi.require_version("Gtk", "3.0")
gi.require_version("Gdk", "3.0")
-from gi.repository import Gtk, Gdk # noqa: E402
+from gi.repository import Gtk, Gdk, GdkPixbuf, GLib, Gio # noqa: E402
+
+
+class GeoReferencerPoint():
+ def __init__(
+ self, x: float, y: float, to_x: float = 0, to_y: float = 0
+ ) -> None:
+ self.x: float = x
+ self.y: float = y
+ self.to_x: float = to_x
+ self.to_y: float = to_y
+
+
+class GeoReferencer():
+ def __init__(self, window) -> None:
+ self.points: list[GeoReferencerPoint] = list()
+ self.window = window
+ if 'pilimage' in self.window:
+ self.img = self.window.pilimage
+
+ def add_point(self, point: GeoReferencerPoint) -> None:
+ self.points.append(point)
+
+ def add_img(self, img) -> None:
+ self.img = img
+
+ def do_transform(self):
+ if len(self.points) < 2:
+ self.window.message_box(
+ "Not enough points for georeferencing available.")
+ return None
+ ratio = get_scale_factor(self.points[0], self.points[1])
+ angle = get_rotation_angle(self.points[0], self.points[1])
+ width = int(self.img.width * ratio)
+ height = int(self.img.height * ratio)
+ self.window.message_box(
+ "w: {}, h: {}, s: {}, a: {}".format(width, height, ratio, angle))
+ resized = self.img.resize(
+ (width, height), Image.Resampling.LANCZOS)
+ rotated = resized.rotate(angle)
+ return rotated
class GeoReferencerWindow(Gtk.Window):
- def __init__(self, svg):
+ def __init__(self, pilimage=None) -> None:
super().__init__(title="Georeferencer")
- self.svg = svg
+ if pilimage:
+ self.add_image(pilimage)
+ self.georeferencer: GeoReferencer = GeoReferencer(self)
self.set_events(Gdk.EventMask.POINTER_MOTION_MASK |
Gdk.EventMask.BUTTON_PRESS_MASK)
- self.box = Gtk.Box()
+ self.box: Gtk.Box = Gtk.Box()
self.add(self.box)
- self.button = Gtk.Button(label="Georeference")
+ self.button: Gtk.Button = Gtk.Button(label="Georeference")
self.button.connect("clicked", self.on_button_clicked)
self.box.pack_start(self.button, True, True, 0)
- self.pix_man = inkex.gui.pixmap.PixmapManager()
- self.pixmap = self.pix_man.get_pixmap(self.svg)
- self.event_box = Gtk.EventBox()
- self.image = Gtk.Image.new_from_pixbuf(self.pixmap)
- self.event_box.add(self.image)
+ self.event_box: Gtk.EventBox = Gtk.EventBox()
self.event_box.set_above_child(above_child=True)
self.event_box.connect('motion-notify-event', self.on_motion_notify)
self.event_box.connect('enter-notify-event', self.on_motion_notify)
self.event_box.connect('button-press-event', self.on_mouse_click)
self.box.pack_start(self.event_box, True, True, 0)
self.connect("destroy", Gtk.main_quit)
+ self.show_all()
- def on_button_clicked(self, widget):
- self.destroy()
+ def message_box(self, message: str):
+ dialog = Gtk.MessageDialog(transient_for=self,
+ modal=False, destroy_with_parent=True,
+ message_type=Gtk.MessageType.INFO,
+ buttons=Gtk.ButtonsType.OK,
+ text=message)
+ dialog.show_all()
+ dialog.run()
+ dialog.destroy()
- def on_motion_notify(self, widget, event):
+ def on_button_clicked(self, widget) -> None:
+ gtkimage = pil_to_gtk(self.georeferencer.do_transform())
+ self.event_box.remove(self.gtkimage)
+ self.gtkimage = gtkimage
+ self.event_box.add(self.gtkimage)
+ self.gtkimage.show_all()
+ self.queue_draw()
+ # self.destroy()
+
+ def on_motion_notify(self, widget, event) -> None:
widget.set_tooltip_text("x:{}, y:{}".format(event.x, event.y))
- def on_mouse_click(self, widget, event):
- widget.set_tooltip_text("HAHA x:{}, y:{}".format(event.x, event.y))
+ def on_mouse_click(self, widget, event) -> None:
+ dialog = Gtk.MessageDialog(transient_for=self,
+ modal=True, destroy_with_parent=True,
+ message_type=Gtk.MessageType.QUESTION,
+ buttons=Gtk.ButtonsType.OK_CANCEL,
+ text="Set new coordinates")
+ point_box = dialog.get_content_area()
+ x_label = Gtk.Label()
+ y_label = Gtk.Label()
+ x_label.set_text("x:")
+ y_label.set_text("y:")
+ x_entry = Gtk.Entry()
+ y_entry = Gtk.Entry()
+ point_box.pack_start(x_label, True, True, 0)
+ point_box.pack_start(x_entry, True, True, 0)
+ point_box.pack_start(y_label, True, True, 0)
+ point_box.pack_start(y_entry, True, True, 0)
+ dialog.show_all()
+ response = dialog.run()
+ if response == Gtk.ResponseType.OK:
+ if x_entry.get_text() and y_entry.get_text():
+ to_x = float(x_entry.get_text())
+ to_y = float(y_entry.get_text())
+ point = GeoReferencerPoint(event.x, event.y, to_x, to_y)
+ self.georeferencer.add_point(point)
+ dialog.destroy()
+
+ def add_image(self, pilimage, mimetype):
+ self.pilimage = pilimage
+ self.georeferencer.add_img(pilimage)
+ self.gtkimage = pil_to_gtk(pilimage, mimetype, window=self)
+ self.event_box.add(self.gtkimage)
+ self.event_box.show_all()
+
+
+def pil_to_gtk(pilimage: Image, mimetype, window: GeoReferencerWindow = None):
+ if window:
+ msgfunc = window.message_box
+ else:
+ msgfunc = print
+ glibbytes = GLib.Bytes.new(pilimage.tobytes())
+ if mimetype == "image/png":
+ glibdata = glibbytes.get_data()
+ gdkpixbuf = GdkPixbuf.Pixbuf.new_from_data(
+ glibdata, GdkPixbuf.Colorspace.RGB, True, 8, pilimage.width, pilimage.height, len(
+ pilimage.getbands(
+ ))*pilimage.width, None, None)
+ elif mimetype == "image/jpeg":
+ glibstream = Gio.MemoryInputStream.new_from_bytes(glibbytes)
+ gdkpixbuf = GdkPixbuf.Pixbuf.new_from_stream(glibstream, None)
+ else:
+ msgfunc("Unknown mimetype, can only handle jpg and png")
+
+ gtkimage = Gtk.Image()
+ gtkimage.set_from_pixbuf(gdkpixbuf)
+ return gtkimage
+
+
+def get_scale_factor(a: GeoReferencerPoint, b: GeoReferencerPoint) -> float:
+ mag_v = ((b.x - a.x)*(b.x - a.x)) + ((b.y - a.y)*(b.y - a.y))
+ mag_w = ((b.to_x - a.to_x)*(b.to_x - a.to_x)) + \
+ ((b.to_y - a.to_y)*(b.to_y - a.to_y))
+ return mag_w/mag_v
+
+
+def get_dot_product(a: GeoReferencerPoint, b: GeoReferencerPoint) -> float:
+ a1 = b.x-a.x
+ a2 = b.to_x - a.to_x
+ b1 = b.y - a.y
+ b2 = b.to_y - a.to_y
+ return (a1*b1) + (a2*b2)
+
+
+def get_rotation_angle(a: GeoReferencerPoint, b: GeoReferencerPoint) -> float:
+ dot = get_dot_product(a, b)
+ mag_v = ((b.x - a.x)*(b.x - a.x)) + ((b.y - a.y)*(b.y - a.y))
+ mag_w = ((b.to_x - a.to_x)*(b.to_x - a.to_x)) + \
+ ((b.to_y - a.to_y)*(b.to_y - a.to_y))
+ return (((dot/mag_v) / mag_w)*(180/math.pi))
class CoordinatesExtension(inkex.EffectExtension):
+ def __init__(self, *args, **kwargs):
+ super().__init__(*args, **kwargs)
+ self.window: GeoReferencerWindow = GeoReferencerWindow()
+ self.image_mimetype = str()
+
+ def effect(self) -> None:
+ images = self.svg.selection.get(IImage)
+ for elem in images:
+ xlink = elem.get("xlink:href")
+ if xlink is not None and xlink[:5] == "data:":
+ data = xlink[5:]
+ (mimetype, data) = data.split(";", 1)
+ self.image_mimetype = mimetype
+ (base, data) = data.split(",", 1)
+ if base != "base64":
+ self.window.message_box(
+ "Unable to decode encoding {}.").format(base)
+ return
+ else:
+ imgdata = base64.b64decode(data)
+ pilimage = Image.open(io.BytesIO(imgdata))
- def effect(self):
- self.window = GeoReferencerWindow(self.svg.tostring())
- self.window.show_all()
- self.eventloop = Gtk.main()
+ if not pilimage:
+ self.window.message_box("Could not find image in selection")
+ self.window.show_all()
+ self.window.destroy()
+ else:
+ self.window.add_image(pilimage, mimetype)
+ self.window.show_all()
+ Gtk.main()
if __name__ == '__main__':
diff --git a/coordinates_extension.py.faulty b/coordinates_extension.py.faulty
new file mode 100755
index 0000000..2cdc4ee
--- /dev/null
+++ b/coordinates_extension.py.faulty
@@ -0,0 +1,228 @@
+#!/usr/bin/env python3
+# coding=utf-8
+#
+# Copyright (C) 2022 Mikael Nordin, hej@mic.ke
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA.
+#
+"""
+Description of this extension
+"""
+import gi
+import math
+import io
+import inkex
+import base64
+from inkex import Image as IImage
+from PIL import Image
+
+gi.require_version("Gtk", "3.0")
+gi.require_version("Gdk", "3.0")
+from gi.repository import Gtk, Gdk, GdkPixbuf, GLib # noqa: E402
+
+
+class GeoReferencerPoint():
+ def __init__(
+ self, x: float, y: float, to_x: float = 0, to_y: float = 0
+ ) -> None:
+ self.x: float = x
+ self.y: float = y
+ self.to_x: float = to_x
+ self.to_y: float = to_y
+
+
+class GeoReferencer():
+ def __init__(self, window) -> None:
+ self.points: list[GeoReferencerPoint] = list()
+ self.window = window
+ if 'pilimage' in self.window:
+ self.img = self.window.pilimage
+
+ def add_point(self, point: GeoReferencerPoint) -> None:
+ self.points.append(point)
+
+ def add_img(self, img) -> None:
+ self.img = img
+
+ def do_transform(self):
+ if len(self.points) < 2:
+ self.window.message_box(
+ "Not enough points for georeferencing available.")
+ return None
+ ratio = get_scale_factor(self.points[0], self.points[1])
+ angle = get_rotation_angle(self.points[0], self.points[1])
+ width = int(self.img.width * ratio)
+ height = int(self.img.height * ratio)
+ self.window.message_box(
+ "w: {}, h: {}, s: {}, a: {}".format(width, height, ratio, angle))
+ resized = self.img.resize(
+ (width, height), Image.Resampling.LANCZOS)
+ rotated = resized.rotate(angle)
+ return rotated
+
+
+class GeoReferencerWindow(Gtk.Window):
+ def __init__(self, pilimage=None) -> None:
+ super().__init__(title="Georeferencer")
+ if pilimage:
+ self.add_image(pilimage)
+ self.georeferencer: GeoReferencer = GeoReferencer(self)
+ self.set_events(Gdk.EventMask.POINTER_MOTION_MASK |
+ Gdk.EventMask.BUTTON_PRESS_MASK)
+ self.box: Gtk.Box = Gtk.Box()
+ self.add(self.box)
+ self.button: Gtk.Button = Gtk.Button(label="Georeference")
+ self.button.connect("clicked", self.on_button_clicked)
+ self.box.pack_start(self.button, True, True, 0)
+ self.event_box: Gtk.EventBox = Gtk.EventBox()
+ self.event_box.set_above_child(above_child=True)
+ self.event_box.connect('motion-notify-event', self.on_motion_notify)
+ self.event_box.connect('enter-notify-event', self.on_motion_notify)
+ self.event_box.connect('button-press-event', self.on_mouse_click)
+ self.box.pack_start(self.event_box, True, True, 0)
+ self.connect("destroy", Gtk.main_quit)
+ self.show_all()
+
+ def message_box(self, message: str):
+ dialog = Gtk.MessageDialog(transient_for=self,
+ modal=False, destroy_with_parent=True,
+ message_type=Gtk.MessageType.INFO,
+ buttons=Gtk.ButtonsType.OK,
+ text=message)
+ dialog.show_all()
+ dialog.run()
+ dialog.destroy()
+
+ def on_button_clicked(self, widget) -> None:
+ gtkimage = pil_to_gtk(self.georeferencer.do_transform())
+ self.event_box.remove(self.gtkimage)
+ self.gtkimage = gtkimage
+ self.event_box.add(self.gtkimage)
+ self.gtkimage.show_all()
+ self.queue_draw()
+ # self.destroy()
+
+ def on_motion_notify(self, widget, event) -> None:
+ widget.set_tooltip_text("x:{}, y:{}".format(event.x, event.y))
+
+ def on_mouse_click(self, widget, event) -> None:
+ dialog = Gtk.MessageDialog(transient_for=self,
+ modal=True, destroy_with_parent=True,
+ message_type=Gtk.MessageType.QUESTION,
+ buttons=Gtk.ButtonsType.OK_CANCEL,
+ text="Set new coordinates")
+ point_box = dialog.get_content_area()
+ x_label = Gtk.Label()
+ y_label = Gtk.Label()
+ x_label.set_text("x:")
+ y_label.set_text("y:")
+ x_entry = Gtk.Entry()
+ y_entry = Gtk.Entry()
+ point_box.pack_start(x_label, True, True, 0)
+ point_box.pack_start(x_entry, True, True, 0)
+ point_box.pack_start(y_label, True, True, 0)
+ point_box.pack_start(y_entry, True, True, 0)
+ dialog.show_all()
+ response = dialog.run()
+ if response == Gtk.ResponseType.OK:
+ if x_entry.get_text() and y_entry.get_text():
+ to_x = float(x_entry.get_text())
+ to_y = float(y_entry.get_text())
+ point = GeoReferencerPoint(event.x, event.y, to_x, to_y)
+ self.georeferencer.add_point(point)
+ dialog.destroy()
+
+ def add_image(self, pilimage):
+ self.pilimage = pilimage
+ self.georeferencer.add_img(pilimage)
+ self.gtkimage = pil_to_gtk(pilimage, window=self)
+ self.event_box.add(self.gtkimage)
+ self.event_box.show_all()
+
+
+def pil_to_gtk(pilimage: Image, window: GeoReferencerWindow = None):
+ if window:
+ msgfunc = window.message_box
+ else:
+ msgfunc = print
+ glibbytes = GLib.Bytes.new(pilimage.tobytes())
+ glibdata = glibbytes.get_data()
+ msgfunc(len(glibdata))
+ gdkpixbuf = GdkPixbuf.Pixbuf.new_from_data(
+ glibdata, GdkPixbuf.Colorspace.RGB, True, 8, pilimage.width, pilimage.height, len(
+ pilimage.getbands(
+ ))*pilimage.width, None, None)
+
+ gtkimage = Gtk.Image()
+ gtkimage.set_from_pixbuf(gdkpixbuf)
+ return gtkimage
+
+
+def get_scale_factor(a: GeoReferencerPoint, b: GeoReferencerPoint) -> float:
+ mag_v = ((b.x - a.x)*(b.x - a.x)) + ((b.y - a.y)*(b.y - a.y))
+ mag_w = ((b.to_x - a.to_x)*(b.to_x - a.to_x)) + \
+ ((b.to_y - a.to_y)*(b.to_y - a.to_y))
+ return mag_w/mag_v
+
+
+def get_dot_product(a: GeoReferencerPoint, b: GeoReferencerPoint) -> float:
+ a1 = b.x-a.x
+ a2 = b.to_x - a.to_x
+ b1 = b.y - a.y
+ b2 = b.to_y - a.to_y
+ return (a1*b1) + (a2*b2)
+
+
+def get_rotation_angle(a: GeoReferencerPoint, b: GeoReferencerPoint) -> float:
+ dot = get_dot_product(a, b)
+ mag_v = ((b.x - a.x)*(b.x - a.x)) + ((b.y - a.y)*(b.y - a.y))
+ mag_w = ((b.to_x - a.to_x)*(b.to_x - a.to_x)) + \
+ ((b.to_y - a.to_y)*(b.to_y - a.to_y))
+ return (((dot/mag_v) / mag_w)*(180/math.pi))
+
+
+class CoordinatesExtension(inkex.EffectExtension):
+ def __init__(self, *args, **kwargs):
+ super().__init__(*args, **kwargs)
+ self.window: GeoReferencerWindow = GeoReferencerWindow()
+
+ def effect(self) -> None:
+ images = self.svg.selection.get(IImage)
+ for elem in images:
+ xlink = elem.get("xlink:href")
+ if xlink is not None and xlink[:5] == "data:":
+ data = xlink[5:]
+ (mimetype, data) = data.split(";", 1)
+ (base, data) = data.split(",", 1)
+ if base != "base64":
+ self.debug_box(
+ "Unable to decode encoding {}.").format(base)
+ else:
+ imgdata = base64.b64decode(data)
+ pilimage = Image.open(io.BytesIO(imgdata))
+
+ if not pilimage:
+ self.window.message_box("Could not find image in selection")
+ self.window.show_all()
+ self.window.destroy()
+ else:
+ self.window.add_image(pilimage)
+ self.window.show_all()
+ Gtk.main()
+
+
+if __name__ == '__main__':
+ CoordinatesExtension().run()
diff --git a/coordinates_extension.py.old b/coordinates_extension.py.old
new file mode 100755
index 0000000..7f18c6d
--- /dev/null
+++ b/coordinates_extension.py.old
@@ -0,0 +1,159 @@
+#!/usr/bin/env python3
+# coding=utf-8
+#
+# Copyright (C) 2022 Mikael Nordin, hej@mic.ke
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA.
+#
+"""
+Description of this extension
+"""
+import inkex
+from inkex import Image as IImage
+import gi
+import io
+import base64
+from PIL import Image
+
+gi.require_version("Gtk", "3.0")
+gi.require_version("Gdk", "3.0")
+from gi.repository import Gtk, Gdk # noqa: E402
+
+
+class GeoReferencerPoint():
+ def __init__(self, x: int, y: int, to_x: int = 0, to_y: int = 0) -> None:
+ self.x: int = x
+ self.y: int = y
+ self.to_x: int = to_x
+ self.to_y: int = to_y
+
+
+class GeoReferencer():
+ def __init__(self, window) -> None:
+ self.points: list[GeoReferencerPoint] = list()
+ self.window = window
+
+ def add_point(self, point: GeoReferencerPoint) -> None:
+ self.points.append(point)
+
+ def add_img(self, img) -> None:
+ self.img = img
+
+ def do_transform(self):
+ pass
+
+
+class GeoReferencerWindow(Gtk.Window):
+ def __init__(self) -> None:
+ super().__init__(title="Georeferencer")
+ self.georeferencer: GeoReferencer = GeoReferencer(self)
+ self.set_events(Gdk.EventMask.POINTER_MOTION_MASK |
+ Gdk.EventMask.BUTTON_PRESS_MASK)
+ self.box: Gtk.Box = Gtk.Box()
+ self.add(self.box)
+ self.button: Gtk.Button = Gtk.Button(label="Georeference")
+ self.button.connect("clicked", self.on_button_clicked)
+ self.box.pack_start(self.button, True, True, 0)
+ self.event_box: Gtk.EventBox = Gtk.EventBox()
+ self.event_box.set_above_child(above_child=True)
+ self.event_box.connect('motion-notify-event', self.on_motion_notify)
+ self.event_box.connect('enter-notify-event', self.on_motion_notify)
+ self.event_box.connect('button-press-event', self.on_mouse_click)
+ self.box.pack_start(self.event_box, True, True, 0)
+ self.connect("destroy", Gtk.main_quit)
+
+ def debug_box(self, message: str):
+ dialog = Gtk.MessageDialog(transient_for=self,
+ modal=False, destroy_with_parent=True,
+ message_type=Gtk.MessageType.INFO,
+ buttons=Gtk.ButtonsType.OK,
+ text=message)
+ dialog.show_all()
+ dialog.run()
+ dialog.destroy()
+
+ def on_button_clicked(self, widget) -> None:
+ img = self.georeferencer.do_transform()
+ self.event_box.remove(self.image)
+ self.image = img
+ self.event_box.add(self.image)
+ self.image.show_all()
+ self.queue_draw()
+ # self.destroy()
+
+ def on_motion_notify(self, widget, event) -> None:
+ widget.set_tooltip_text("x:{}, y:{}".format(event.x, event.y))
+
+ def on_mouse_click(self, widget, event) -> None:
+ dialog = Gtk.MessageDialog(transient_for=self,
+ modal=True, destroy_with_parent=True,
+ message_type=Gtk.MessageType.QUESTION,
+ buttons=Gtk.ButtonsType.OK_CANCEL,
+ text="Set new coordinates")
+ point_box = dialog.get_content_area()
+ x_label = Gtk.Label()
+ y_label = Gtk.Label()
+ x_label.set_text("x:")
+ y_label.set_text("y:")
+ x_entry = Gtk.Entry()
+ y_entry = Gtk.Entry()
+ point_box.pack_start(x_label, True, True, 0)
+ point_box.pack_start(x_entry, True, True, 0)
+ point_box.pack_start(y_label, True, True, 0)
+ point_box.pack_start(y_entry, True, True, 0)
+ dialog.show_all()
+ response = dialog.run()
+ if response == Gtk.ResponseType.OK:
+ to_x = int(x_entry.get_text())
+ to_y = int(y_entry.get_text())
+ point = GeoReferencerPoint(event.x, event.y, to_x, to_y)
+ self.georeferencer.add_point(point)
+ dialog.destroy()
+
+ def add_image(self, img):
+ self.image = img
+ self.georeferencer.add_img(self.image)
+ self.event_box.add(self.image)
+ self.show_all()
+
+
+class CoordinatesExtension(inkex.EffectExtension):
+ def __init__(self, *args, **kwargs):
+ super().__init__(*args, **kwargs)
+ self.window: GeoReferencerWindow = GeoReferencerWindow()
+
+ def effect(self) -> None:
+ images = self.svg.selection.get(IImage)
+ for elem in images:
+ xlink = elem.get("xlink:href")
+ if xlink is not None and xlink[:5] == "data:":
+ data = xlink[5:]
+ (mimetype, data) = data.split(";", 1)
+ (base, data) = data.split(",", 1)
+ if base != "base64":
+ self.debug_box(
+ "Unable to decode encoding {}.").format(base)
+ else:
+ imgdata = base64.b64decode(data)
+ image = Image.open(io.BytesIO(imgdata))
+
+ self.window.add_image(image)
+ self.window.show_all()
+ Gtk.main()
+
+
+if __name__ == '__main__':
+ CoordinatesExtension().run()