[GRASS-SVN] r40359 - in grass/trunk/scripts: . wxpyimgview

svn_grass at osgeo.org svn_grass at osgeo.org
Sun Jan 10 01:00:41 EST 2010


Author: glynn
Date: 2010-01-10 01:00:41 -0500 (Sun, 10 Jan 2010)
New Revision: 40359

Added:
   grass/trunk/scripts/wxpyimgview/
   grass/trunk/scripts/wxpyimgview/Makefile
   grass/trunk/scripts/wxpyimgview/wxpyimgview.html
   grass/trunk/scripts/wxpyimgview/wxpyimgview.py
   grass/trunk/scripts/wxpyimgview/wxpyimgview_gui.py
Log:
wxPython version of wximgview


Added: grass/trunk/scripts/wxpyimgview/Makefile
===================================================================
--- grass/trunk/scripts/wxpyimgview/Makefile	                        (rev 0)
+++ grass/trunk/scripts/wxpyimgview/Makefile	2010-01-10 06:00:41 UTC (rev 40359)
@@ -0,0 +1,10 @@
+MODULE_TOPDIR = ../..
+
+PGM = wxpyimgview
+
+include $(MODULE_TOPDIR)/include/Make/Script.make
+
+default: script $(ETC)/wxpyimgview_gui.py
+
+$(ETC)/%: %
+	$(INSTALL) $< $@

Added: grass/trunk/scripts/wxpyimgview/wxpyimgview.html
===================================================================
--- grass/trunk/scripts/wxpyimgview/wxpyimgview.html	                        (rev 0)
+++ grass/trunk/scripts/wxpyimgview/wxpyimgview.html	2010-01-10 06:00:41 UTC (rev 40359)
@@ -0,0 +1,26 @@
+<h2>DESCRIPTION</h2>
+
+<i>wxpyimgview</i> is a simple wxWidgets image viewer for 32-bpp BMP images, as
+can be created with the <em><a href="pngdriver.html">PNG</a></em> and
+<em><a href="cairodriver.html">cairo</a></em> drivers. The display is
+continually refreshed.
+
+<h2>NOTES</h2>
+
+The display driver must be configure to map the file, with
+<em>GRASS_PNG_MAPPED=TRUE</em>. This ensures that the file will remain
+a constant size, rather than being truncated whenever it is updated.
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a href="pngdriver.html">PNG driver</a>
+<a href="cairodriver.html">cairo driver</a>
+</em>
+
+
+<h2>AUTHOR</h2>
+Glynn Clements
+
+<p>
+<i>Last changed: $Date: 2008-08-15 07:16:42 +0100 (Fri, 15 Aug 2008) $</i>

Added: grass/trunk/scripts/wxpyimgview/wxpyimgview.py
===================================================================
--- grass/trunk/scripts/wxpyimgview/wxpyimgview.py	                        (rev 0)
+++ grass/trunk/scripts/wxpyimgview/wxpyimgview.py	2010-01-10 06:00:41 UTC (rev 40359)
@@ -0,0 +1,54 @@
+#!/usr/bin/env python
+
+############################################################################
+#
+# MODULE:       wxpyimgview
+# AUTHOR(S):    Glynn Clements <glynn at gclements.plus.com>
+# COPYRIGHT:    (C) 2010 Glynn Clements
+#
+#  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.
+#
+#############################################################################/
+
+#%Module
+#% description: View BMP images from the PNG driver.
+#% keywords: display
+#% keywords: raster
+#%End
+#%Option
+#% key: image
+#% type: string
+#% required: yes
+#% multiple: no
+#% description: Image file
+#% gisprompt: old_file,file,input
+#%End
+#%Option
+#% key: percent
+#% type: integer
+#% required: no
+#% multiple: no
+#% description: Percentage of CPU time to use
+#% answer: 10
+#%End
+
+import sys
+import os
+import grass.script as grass
+
+if __name__ == "__main__":
+    options, flags = grass.parser()
+    image   = options['image']
+    percent = options['percent']
+    python = os.getenv('GRASS_PYTHON', 'python')
+    gisbase = os.environ['GISBASE']
+    script = os.path.join(gisbase, "etc", "wxpyimgview_gui.py")
+    os.execlp(python, script, script, image, percent)

Added: grass/trunk/scripts/wxpyimgview/wxpyimgview_gui.py
===================================================================
--- grass/trunk/scripts/wxpyimgview/wxpyimgview_gui.py	                        (rev 0)
+++ grass/trunk/scripts/wxpyimgview/wxpyimgview_gui.py	2010-01-10 06:00:41 UTC (rev 40359)
@@ -0,0 +1,173 @@
+#!/usr/bin/env python
+
+############################################################################
+#
+# MODULE:       wxpyimgview
+# AUTHOR(S):    Glynn Clements <glynn at gclements.plus.com>
+# COPYRIGHT:    (C) 2010 Glynn Clements
+#
+#  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.
+#
+#############################################################################/
+
+#%Module
+#% description: View BMP images from the PNG driver.
+#% keywords: display
+#% keywords: raster
+#%End
+#%Option
+#% key: image
+#% type: string
+#% required: yes
+#% multiple: no
+#% description: Image file
+#% gisprompt: old_file,file,input
+#%End
+#%Option
+#% key: percent
+#% type: integer
+#% required: no
+#% multiple: no
+#% description: Percentage of CPU time to use
+#% answer: 10
+#%End
+
+import sys
+import struct
+import numpy
+import time
+import signal
+
+import wxversion
+wxversion.select('2.8')
+import wx
+
+class Frame(wx.Frame):
+    title = "Image Viewer"
+
+    def __init__(self, app, size):
+	self.app = app
+	wx.Frame.__init__(self, None, title = Frame.title, size = size)
+	self.Create()
+
+    def Create(self):
+	self.Bind(wx.EVT_ERASE_BACKGROUND, self.erase)
+	self.Bind(wx.EVT_PAINT, self.redraw)
+
+	self.Bind(wx.EVT_TIMER, self.tick, id = 1)
+	self.timer = wx.Timer(self, 1)
+	self.timer.Start(100, True)
+
+	# Python doesn't receive signals while wx is waiting for an event
+	self.Bind(wx.EVT_TIMER, self.dummy, id = 2)
+	self.ticker = wx.Timer(self, 2)
+	self.ticker.Start(100, False)
+
+    def erase(self, ev):
+	ev.GetDC();
+
+    def draw(self):
+	app = self.app
+	size = self.GetSize()
+	x0 = (size.GetWidth()  - app.i_width) / 2
+	y0 = (size.GetHeight() - app.i_height) / 2
+	dc = wx.PaintDC(self)
+	data = app.imgbuf.reshape((app.i_height, app.i_width, 4))
+	data = data[::,::,2::-1]
+	image = wx.ImageFromData(app.i_width, app.i_height, data.tostring())
+	dc.DrawBitmap(wx.BitmapFromImage(image), x0, y0, False)
+
+    def redraw(self, ev):
+	if self.app.fraction > 0.001:
+	    t0 = time.time()
+	    self.draw()
+	    t1 = time.time()
+
+	    last = t1 - t0
+	    delay = last / self.app.fraction
+	    self.timer.Start(int(delay * 1000), True)
+	else:
+	    self.draw()
+
+    def tick(self, ev):
+	self.Refresh()
+
+    def dummy(self, ev):
+	pass
+
+class Application(wx.App):
+    def __init__(self):
+	self.image = sys.argv[1]
+	self.fraction = int(sys.argv[2]) / 100.0
+	self.HEADER_SIZE = 54
+	wx.App.__init__(self)
+
+    def read_bmp_header(self, header):
+	magic, bmfh, bmih = struct.unpack("2s12s40s", header)
+
+	if magic != 'BM':
+	    raise SyntaxError("Invalid magic number")
+
+	size, res1, res2, hsize = struct.unpack("<IHHI", bmfh)
+
+	if hsize != self.HEADER_SIZE:
+	    raise SyntaxError("Invalid file header size")
+
+	hsize, width, height, planes, bpp, compression, imsize, xppm, yppm, cused, cimp = \
+	       struct.unpack("<IiiHHIIiiII", bmih)
+
+	if hsize != 40:
+	    raise SyntaxError("Invalid info header size")
+
+	self.i_width = width
+	self.i_height = -height
+
+	if planes != 1:
+	    raise SyntaxError("Planar data not supported")
+	if bpp != 32:
+	    raise SyntaxError("Only 32-BPP images supported")
+	if compression != 0:
+	    raise SyntaxError("Compression not supported")
+	if imsize != self.i_width * self.i_height * 4:
+	    raise SyntaxError("Invalid image data size")
+	if size != self.HEADER_SIZE + self.i_width * self.i_height * 4:
+	    raise SyntaxError("Invalid image size")
+
+    def map_file(self):
+	f = open(self.image, 'r')
+
+	header = f.read(self.HEADER_SIZE)
+	self.read_bmp_header(header)
+
+	self.imgbuf = numpy.memmap(f, mode = 'r', offset = self.HEADER_SIZE)
+
+    def signal_handler(self, sig, frame):
+	wx.CallAfter(self.mainwin.Refresh);
+
+    def set_handler(self):
+	if 'SIGUSR1' in dir(signal):
+	    signal.signal(signal.SIGUSR1, self.signal_handler)
+
+    def OnInit(self):
+	self.map_file()
+
+	size = wx.Size(self.i_width, self.i_height)
+	self.mainwin = Frame(self, size)
+	self.mainwin.Show()
+	self.SetTopWindow(self.mainwin)
+
+	self.set_handler()
+
+	return True
+
+if __name__ == "__main__":
+    app = Application()
+    app.MainLoop()



More information about the grass-commit mailing list