#!/usr/bin/env python3 ############################################################################ # # MODULE: wxpyimgview # AUTHOR(S): Glynn Clements # 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: Views BMP images from the PNG driver. # % keyword: display # % keyword: raster # %end # %option G_OPT_F_INPUT # % key: image # % description: Name of input image file # %end # %option # % key: percent # % type: integer # % required: no # % multiple: no # % description: Percentage of CPU time to use # % answer: 10 # %end import signal import struct import sys import time import numpy import wx import grass.script as grass from grass.script.setup import set_gui_path set_gui_path() from gui_core.wrap import BitmapFromImage # noqa: E402 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] fn = getattr(data, "tobytes", getattr(data, "tostring")) image = wx.Image(app.i_width, app.i_height, fn()) dc.DrawBitmap(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 = 64 wx.App.__init__(self) def read_bmp_header(self, header): magic, bmfh, bmih = struct.unpack("2s12s40s10x", header) if grass.decode(magic) != "BM": raise SyntaxError("Invalid magic number") size, res1, res2, hsize = struct.unpack("