URI:
       timgtrans.py - imgtrans - interactive BMP to txt converter
  HTML git clone git://src.adamsgaard.dk/imgtrans
   DIR Log
   DIR Files
   DIR Refs
   DIR LICENSE
       ---
       timgtrans.py (8881B)
       ---
            1 #!/usr/bin/env python
            2 
            3 import sys, os
            4 import argparse
            5 import scipy.ndimage
            6 import scipy.misc
            7 import scipy.cluster
            8 import numpy
            9 import matplotlib
           10 matplotlib.use('WXAgg')
           11 import matplotlib.figure
           12 import matplotlib.backends
           13 import matplotlib.backends.backend_wxagg
           14 import matplotlib.pyplot
           15 import wx
           16 
           17 
           18 class ImgTrans:
           19 
           20     def __init__(self):
           21         self.img = numpy.zeros(3)
           22 
           23     def read_image(self, infile):
           24         try:
           25             self.img = scipy.ndimage.imread(infile)
           26         except IOError:
           27             sys.stderr.write('could not open input file "' + infile + '"\n')
           28 
           29         self.orig_img = self.img.copy()
           30 
           31     def down_sample(self, width):
           32         hw_ratio = float(self.orig_img.shape[0])/self.orig_img.shape[1]
           33         size = (int(round(hw_ratio*width)), width)
           34         self.img = scipy.misc.imresize(self.orig_img, size)
           35 
           36     def limit_colors(self, ncolors):
           37         ar = self.img.reshape(scipy.product(self.img.shape[:2]),\
           38                 self.img.shape[2])
           39         self.colors, dist = scipy.cluster.vq.kmeans(ar, ncolors)
           40         tmp = ar.copy()
           41         vecs, dist = scipy.cluster.vq.vq(ar, self.colors)
           42         for i, color in enumerate(self.colors):
           43             tmp[scipy.r_[scipy.where(vecs == i)],:] = color
           44         self.img = tmp.reshape(self.img.shape[0], self.img.shape[1], 3)
           45 
           46     def convert_256_colors(self):
           47         palette = Palette('256colors')
           48         tmp = self.img.reshape(scipy.product(self.img.shape[:2]),\
           49                 self.img.shape[2])
           50         for i in range(tmp.size/3):
           51             tmp[i] = palette.nearest256color(tmp[i])
           52         self.img = tmp.reshape(self.img.shape[0], self.img.shape[1], 3)
           53 
           54     def save_image(self, filename, grid=True):
           55         fig = matplotlib.pyplot.figure()
           56         imgplot = matplotlib.pyplot.imshow(self.img, interpolation='nearest')
           57         matplotlib.pyplot.grid(grid)
           58         matplotlib.pyplot.savefig(filename)
           59 
           60     def save_txt_file(self, filename):
           61         #import pdb; pdb.set_trace()
           62         out = self.img/numpy.max(self.img)
           63         if self.img.ndim > 2:
           64             out = out[:,:,0]
           65         numpy.savetxt(filename,
           66                 out,
           67                 header='{:d} {:d}'.format(self.img.shape[0], self.img.shape[1]),
           68                 comments='',
           69                 fmt='%1.0f')
           70 
           71     def image(self):
           72         return self.img
           73 
           74 
           75 class MainScreen(wx.Frame):
           76 
           77     def __init__(self, *args, **kwargs):
           78         super(MainScreen, self).__init__(*args, **kwargs)
           79         self.cs = ImgTrans()
           80         self.InitUI()
           81         self.contentNotSaved = False
           82         self.grid = True
           83 
           84     def InitUI(self):
           85 
           86         self.InitMenu()
           87         #self.InitToolbar()
           88         self.InitPreview()
           89 
           90         self.SetSize((600, 600))
           91         self.SetTitle('ImgTrans')
           92         self.Centre()
           93         self.Show(True)
           94 
           95     def InitMenu(self):
           96 
           97         menubar = wx.MenuBar()
           98 
           99         fileMenu = wx.Menu()
          100         fitem = fileMenu.Append(wx.ID_OPEN, 'Open image', 'Open image')
          101         self.Bind(wx.EVT_MENU, self.OnOpen, fitem)
          102         fitem = fileMenu.Append(wx.ID_SAVE, 'Save text file', 'Save text file')
          103         self.Bind(wx.EVT_MENU, self.OnSave, fitem)
          104         fileMenu.AppendSeparator()
          105         fitem = fileMenu.Append(wx.ID_EXIT, 'Quit', 'Quit application')
          106         self.Bind(wx.EVT_MENU, self.OnQuit, fitem)
          107         menubar.Append(fileMenu, '&File')
          108 
          109         helpMenu = wx.Menu()
          110         fitem = helpMenu.Append(wx.ID_ABOUT, 'About', 'About')
          111         self.Bind(wx.EVT_MENU, self.OnAbout, fitem)
          112         menubar.Append(helpMenu, '&Help')
          113 
          114         self.SetMenuBar(menubar)
          115 
          116     def InitToolbar(self):
          117 
          118         toolbar = self.CreateToolBar()
          119         qtool = toolbar.AddLabelTool(wx.ID_EXIT, 'Quit',
          120                 wx.Bitmap('textit.png'))
          121         self.Bind(wx.EVT_TOOL, self.OnQuit, qtool)
          122 
          123         toolbar.Realize()
          124 
          125     def InitPreview(self):
          126         self.figure = matplotlib.figure.Figure()
          127         self.axes = self.figure.add_subplot(111)
          128         self.canvas = matplotlib.backends.backend_wxagg.FigureCanvasWxAgg(self,
          129                 -1, self.figure)
          130         self.sizer = wx.BoxSizer(wx.VERTICAL)
          131         self.sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
          132         self.SetSizer(self.sizer)
          133         self.Fit()
          134 
          135     def DrawPreview(self):
          136         self.axes.grid(self.grid)
          137         imgplot = self.axes.imshow(self.cs.image(), interpolation='nearest')
          138         imgplot.set_cmap('gray_r')
          139         self.canvas.draw()
          140 
          141     def OnQuit(self, event):
          142         if self.contentNotSaved:
          143             if wx.MessageBox('Current image is not saved! Proceed?',
          144                     'Please confirm', wx.ICON_QUESTION | wx.YES_NO, self) == \
          145                     wx.NO:
          146                         return
          147         self.Close()
          148 
          149     def OnOpen(self, event):
          150         if self.contentNotSaved:
          151             if wx.MessageBox('Current image is not saved! Proceed?',
          152                     'Please confirm', wx.ICON_QUESTION | wx.YES_NO, self) == \
          153                     wx.NO:
          154                         return
          155         
          156         self.dirname = ''
          157         openFileDialog = wx.FileDialog(self, 'Open image file', self.dirname,
          158                 '', 'Image files (*.jpg, *.jpeg, *.png, *.gif, *.bmp)|'
          159                 + '*.jpg;*.jpeg;*.png;*.gif;*.bmp',
          160                 wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
          161 
          162         if openFileDialog.ShowModal() == wx.ID_OK:
          163             self.filename = openFileDialog.GetFilename()
          164             self.dirname = openFileDialog.GetDirectory()
          165             self.cs.read_image(openFileDialog.GetPath())
          166             self.SetTitle('ImgTrans: ' + openFileDialog.GetPath())
          167             self.DrawPreview()
          168         openFileDialog.Destroy()
          169 
          170     def OnSave(self, event):
          171         #saveFileDialog = wx.FileDialog(self, 'Save image file', self.dirname,
          172         #        '', 'PNG files (*.png)|*.png|'
          173         #        + 'JPEG files (*.jpg,*.jpeg)|*.jpg*.jpeg|'
          174         #        + 'GIF files (*.gif)|*.gif|'
          175         #        + 'BMP files (*.bmp)|*.bmp',
          176         #        wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
          177         saveFileDialog = wx.FileDialog(self, 'Save text file', self.dirname,
          178                 '', 'TXT files (*.txt)|*.txt',
          179                 wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
          180         basename = os.path.splitext(self.filename)[0]
          181         saveFileDialog.SetFilename(basename + '.txt')
          182 
          183         if saveFileDialog.ShowModal() == wx.ID_CANCEL:
          184             return
          185 
          186         #self.cs.save_image(saveFileDialog.GetPath(), grid=self.grid)
          187         self.cs.save_txt_file(saveFileDialog.GetPath())
          188         self.contentNotSaved = False
          189 
          190     def OnDownSample(self, event):
          191         dlg = wx.TextEntryDialog(None, 'Enter new width', defaultValue='50')
          192         ret = dlg.ShowModal()
          193         if ret == wx.ID_OK:
          194             width = int(dlg.GetValue())
          195             self.cs.down_sample(int(width))
          196             self.contentNotSaved = True
          197             self.DrawPreview()
          198 
          199     def OnLimitColors(self, event):
          200         dlg = wx.TextEntryDialog(None, 'Enter the number of colors to include',
          201                 defaultValue='16')
          202         ret = dlg.ShowModal()
          203         if ret == wx.ID_OK:
          204             self.cs.limit_colors(int(dlg.GetValue()))
          205             self.contentNotSaved = True
          206             self.DrawPreview()
          207 
          208     def On256Colors(self, event):
          209         self.cs.convert_256_colors()
          210         self.contentNotSaved = True
          211         self.DrawPreview()
          212 
          213     def ToggleGrid(self, event):
          214         if self.gridtoggle.IsChecked():
          215             self.grid = True
          216             self.DrawPreview()
          217         else:
          218             self.grid = False
          219             self.DrawPreview()
          220 
          221     def OnAbout(self, event):
          222 
          223         description = '''ImgTrans is a image converter.'''
          224 
          225         license = '''ImgTrans is free software; you can redistribute it
          226 and/or modify it under the terms of the GNU General Public License as published
          227 by the Free Software Foundation; either version 3 of the License, or (at your
          228 option) any later version.
          229 
          230 ImgTrans is distributed in the hope that it will be useful, but WITHOUT ANY
          231 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
          232 PARTICULAR PURPOSE.
          233 See the GNU General Public License for more details. You should have recieved a
          234 copy of the GNU General Public License along with ImgTrans; if not, write to
          235 the Free Software Foundation, Inc., 59 Temple Palace, Suite 330, Boston, MA
          236 02111-1307  USA'''
          237 
          238         info = wx.AboutDialogInfo()
          239 
          240         info.SetIcon(wx.Icon('icon.png', wx.BITMAP_TYPE_PNG))
          241         info.SetName('ImgTrans')
          242         info.SetVersion('1.0')
          243         info.SetDescription(description)
          244         info.SetCopyright('(C) 2015 Anders Damsgaard')
          245         info.SetWebSite('https://cs.au.dk/~adc')
          246         info.SetLicense(license)
          247         info.AddDeveloper('Anders Damsgaard')
          248         info.AddDocWriter('Anders Damsgaard')
          249         info.AddArtist('Anders Damsgaard')
          250 
          251         wx.AboutBox(info)
          252 
          253 
          254 
          255 def main():
          256     app = wx.App()
          257     MainScreen(None, title='ImgTrans')
          258     app.MainLoop()
          259 
          260 if __name__ == '__main__':
          261     main()