Home
David Gowers' technology
 
[Most Recent Entries] [Calendar View] [Friends]

Below are the 20 most recent journal entries recorded in dgowers_tech's LiveJournal:

    [ << Previous 20 ]
    Thursday, January 1st, 2009
    2:18 pm
    Just released one of my libraries, finally!!!
    pyion

    (requires Python (www.python.org), obviously :)
    if you want to check it out, you can download and unpack a package from the url above, installing in the normal way:
    1. 'python setup.py build'
    2. 'sudo python setup.py install' (if you're running Windows, this command might need to be just 'python setup.py install')

    Or to get an even more up to date version (within the minute, possibly :), get git, and then run the command

    git clone git://repo.or.cz/pyion.git

    from the readme file, here is what pyion contains, roughly:


      * general maths (most functions support both scalars and list/array-likes)
      ** factorials
      ** fast sum of series 1,2,3,4,5 ... N
      ** number of sequences of N size taken from a set of K size
      ** number of places a sequence of length N can be subdivided
      ** round N to nearest power of B
      ** convert a power of B, N, to an exponent of B, such that B**E == N
      ** find common denominator
      ** find all integers that divide evenly into N
      ** linear/spline interpolation of a 1d series of values
      ** binary representation of a number
      * spatial maths
      ** subclassable Grid type
      ** grid snapping and 'is-in-cell'
      ** polar/cartesian transform
      ** polar distance
      ** calculate triple of weights based on position in triangle
      * randomization
      ** return true P% of the time
      ** weighted sampling from a set of items
      ** fill weighted boxes in a roughly even way
      ** randomly dispense contents of a box
      ** convert nested percentage weights to flat 0..1 weights
      ** dice roll (single, and iterative/infinite)
      ** chain iterator, which yields values while percentage chance of success
         rolls succeed, and stops as soon as they fail.
         Like OHRRPGCE 'chain attack/ chain %' option
      * misc
      ** find numeric limits of data types (builtin types or simple numpy types)
      ** sort sequence according to template
      ** reverse of zip (flat sequence a,b,c,a,b,c,a,b,c -> a,b,c tuples)
      ** easily read every line or every byte of a file
      ** calculate minimum number of bits required to store a given integer.
      ** quickly set multiple attributes on an object
      ** Metadata class for easy management of metadata,
         with yaml serialization support.

    * some other things, which are not officially supported ;)

    i'm happy to have finally released it!  and making my changes available through git is ultrasimple, nice and easy, just like git itself :)

    this is in preparation to release my pixlab library, which is the guts of what I tend to poke at in my spare time; it's a comprehensive ehm.. pixel-art-processing library, actually it's really oriented towards what I call PCG, pixel-correct graphics, which often would not be accepted as pixel-art often, because it only considers the exactness of the end result, not whether filtering was used to get there.

    :))
    i'll now go for a run around the block.  i'm already happy cause of this, and running will boost it even more, besides improving my voice markedly :)

    use git, okay! it's fun and easy, it keeps your software safe from any major fuckups you could accidentally inflict on it, it doesn't need you to be online for most operations, and it's also incredibly fast,efficient, and powerful.  it's almost unbelievable how good it is, when one was used to horrors like CVS and Subversion.
    it even handles binary files efficiently, I'm planning to use it to track image history as I paint in GIMP :)

    btw: you don't need sentence-start capitalizations if you format your paragraphs in a non wall-of-text way :) Lojban taught me this.



    Current Mood: happy
    Monday, November 24th, 2008
    3:01 pm
    Scipy vs Numpy 1.3, and SAGE
    Still working on news part G2, which will cover GPixMint.

    If you use Numpy and Scipy, and like to keep them up to date, you should be aware: SVN trunk scipy requires numpy 1.2, and is not compatible with 1.3 yet. There are major changes to the UFunc API, which renders the entire scipy.special module uncompilable (specifically the _cephesmodule.c, which is the core of it). So you can't use SVN numpy in this case.

    ~~~~~~

    On Ubuntu 8.04, painless compilation of Scipy can be had after you modify the umfpack
    section in scipy's site.cfg to look like:

    [umfpack]
    umfpack_libs = umfpack
    include_dirs = /usr/include/suitesparse

    Until now, I had hacked around libsuitesparse -- scipy's site.cfg by default assumes that UMFPACK, AMD, BLAS, ATLAS, etc.. are all installed separately.. This is a proper fix though.

    You need to remember to delete /usr/lib/python-2.5/site-packages/scipy* before installing the newer copy...
    otherwise, obsolete files can get mixed in, which results in Bad Things Happening (also, Confusing Things Happening).

    ~~~~~~

    SAGE is essentially an integrated maths lab. It integrates dozens of other packages such as numpy, scipy, networkx, cython, matplotlib, ipython, . Those are the ones I best know (IMO the only non-obvious one is cython, which allows you to mix python and C code for great speed gains). The others comprise:

    • ATLAS: Automatically Tuned Linear Algebra Software
    • BLAS: Basic Fortan 77 linear algebra routines
    • Cddlib: Double Description Method of Motzkin
    • Common Lisp: Multiparadigm and general-purpose programming language
    • CVXOPT: Convex optimization, linear programming, least squares, etc.
    • F2c: Converts Fortran 77 to C code
    • Flint: Fast Library for Number Theory
    • FpLLL: Euclidian lattice reduction
    • GAP: Groups, Algorithms, Programming
    • GD: Dynamic graphics generation tool
    • Genus2reduction: Curve data computation
    • Gfan: Gröbner fans and tropical varieties
    • Givaro: C++ library for arithmetic and algebra
    • GMP: GNU Multiple Precision Arithmetic Library
    • GMP-ECM: Elliptic Curve Method for Integer Factorization
    • GNU TLS: Secure networking
    • GSL: Gnu Scientific Library
    • JsMath: JavaScript implementation of LaTeX
    • IML: Integer Matrix Library
    • LAPACK: Fortan 77 linear algebra library
    • Lcalc: L-functions calculator
    • Libgcrypt: General purpose cryptographic library
    • Libgpg-error: Common error values for GnuPG components
    • Linbox: C++ linear algebra library
    • M4RI: Linear Algebra over GF(2)
    • Maxima: computer algebra system
    • Mercurial: Revision control system
    • MoinMoin Wiki
    • MPFI: Multiple Precision Floating-point Interval library
    • MPFR: C library for multiple-precision floating-point computations with correct rounding
    • ECLib:Cremona's Programs for Elliptic curves
    • NetworkX: Graph theory
    • NTL: Number theory C++ library
    • OpenCDK: Open Crypto Development Kit
    • PALP: A Package for Analyzing Lattice Polytopes
    • PARI/GP: Number theory calculator
    • Pexpect: Pseudo-tty control for Python
    • PNG: Bitmap image support
    • PolyBoRi: Polynomials Over Boolean Rings
    • PyCrypto: Python Cryptography Toolkit
    • Python: Interpreted language
    • Qd: Quad-double/Double-double Computation Package
    • R: Statistical Computing
    • Rpy: Python interface to R
    • Scipy: Python library for scientific computation
    • Singular: fast commutative and noncommutative algebra
    • SQLite: Relation database
    • Sympow: L-function calculator
    • Symmetrica: Representation theory
    • Sympy: Python library for symbolic computation
    • Tachyon: lightweight 3d ray tracer
    • Termcap: Simplifies the process of writing portable text mode applications
    • Twisted: Python networking library
    • Weave: Tools for including C/C++ code within Python
    • ZODB: Object-oriented database
    (taken from http://www.sagemath.org/links-components.html)

    Yes, that's large (200mb source download, 300mb linux binaries). It's also very big on collaboration, emphasizing its web-based interface with multiple users, multiple notebooks. Though you can still interact with it like you would python, through writing scripts or interacting through a commandline console.

    A review I found:
    http://www.softpedia.com/reviews/linux/Sage-3-0-2-Review-Review-93004.shtml
    The gist of which is 'if you need to experiment mathematically, this is almost sure to help'.

    Notice in the review, how easily a function is plotted. In the bottom-left screenshot, you can see, you just create the variable objects,  specify how they map to the 3d space, create a plot (specifying value ranges for each variable), and show the plot.
    This is much easier than, say, matplotlib.

    I'm impressed. I plan to install it and try it.

    Friday, November 21st, 2008
    10:37 am
    News, part G1
    I've finally begun organizing my python modules (ie. the modules I've personally written); They amount to a lot (~500 modules plus ~1000 miscellanea). How? I was introduced to 'paster', which among other things can easily create a new package with all the necessary information to be published to the PyPI. I proceeded to create 'pixlab', a package for manipulating arrays of colors (ie. images) and migrate some of my old code in. pixlab has been slowly evolving, and I turned the guts of GPixMint (was called GVM a few posts ago, that shows how long I have not posted in!) into another module. I created a package 'gimplets' for my GIMP-specific code. I try to keep it very specific -- gimplets typically just contains 'neat macroizations' whereas pixlab contains actual algorithyms

    Paster can be obtained by running
    "sudo easy_install PasteScript" (or just 'easy_install PasteScript' on Windows AFAIK)

    How to use paster in one line:
    run "paster create". You'll be prompted for various details including the name of your project, the version, it's dependencies, your name and email address, and eventually paster will create a directory named after your project (eg 'pixlab/'), with all necessary files. you then move any source .py files that should be included into eg 'pixlab/pixlab/' or a subdirectory thereof.. Then you can do the usual 'python setup.py build' to build it, 'sudo python setup.py install' to install or 'sudo python setup.py install'

    Pixlab was motivated by my desire for a simple, flexible way to manipulate colors, palettes, and swatches. It provides the following 'stock' color types
    • RGB
    • LAB
    • LCH
    • GRAY
    • INDEXED (beta quality)
    with the following built-in profiles (profiles describe properties of a particular colorspace)
    • rgb # (linear RGB)
    • rgbp # (this is what you might normally expect to send to the display, or download off the web --  aka gamma-adjusted sRGB)
    • cpc, ega64, genesis, amiga, snes, 15bit, 16bit, vga, 24bit (quantized colorspaces)
    • lab
    • lch # (a polar view of L*ab space, similar to a saner version of HSL)
    • indexed
    Supporting N-dimensional color-arrays with the help of Numpy; one quirk is that an image such as
    [[[0],[1]],[[2],[3]]]
    is 3-dimensional, not 2. that is, the last dimension is color; the only time <2d arrays happen is with single colors.
    Extra channels can be used and are transparently preserved during colorspace conversion.
    Data type can vary. In typical processing, dtype is going to be either 32bit float or 64bit float. With indexed, only integral, unsigned data types <= 32bits are allowed
    Quantized colorspaces such as CPC use floating point by default even though only integral values are meaningful -- this makes it easy to calculate accurate color mixings, only applying quantization when the
    final conversion back to rgbp occurs.

    I realize I've been getting very technical here, so have a screenshot of a toy app (4k sourcecode / 150 lines) I made using pixlab and pygtk. You can select a color, which is then automatically quantized if needed to fit in the destination color space, and then it is propagated to all other entries, so you can see, what is the closest color in Amiga, Genesis, CPC, Snes,. VGA color spaces, and what their numeric values are. You can also input color values directly (though the results may surprise you for LCH and LAB, since only part of their gamut is within sRGB gamut)



    The motivation and systemization behind this shall become more apparent in part G2

    7:18 am
    Hello!
    44 weeks since my last post!

    Part of the reason for that: LJ's changes in ToS make me wary.
    Another is: my tendency to treat my life as too full, which is only true if you believe that everything must have just the same (full) attention; A habit I am dispensing with.

    News? A truckload, yes.

    In this post, the obligatory software promotion, with all the aspects I particularly use myself.
    • Gimp 2.6 is well worth the trouble of upgrading, including such things as
      • smoother drawing (as in, both faster and higher quality -- and Alexia Death is working on even better smoothing for Gimp 2.7.)
      • 'favorites' system for color tools (most handy with color balance, levels, curves for me)
      • track recent color tool options automatically (eg. the last 50 'Levels' settings you used)
      • Menus only on images
      • Hybrid polygon/free select tool -- this is a real work of art, a joy to use, esp. the adjustment power available
      • GEGL-tool which provides all of the stock GEGL operations. I use 'Bilateral filter' a lot -- it's a kind of blur that does not include pixels too different from the current pixel.Very effective for smoothing an area without having the background color eat into your object's color (as happens with Gauss-blur, Selective-Gauss-blur).  'median-filter' is handy for eliminating small details so when an image is scaled down it looks cleaner.
      • Far better paint dynamics; previously you only had pressure-dependence..now, you have a grid with 'pressure velocity random' down one side, and the possible variables (like 'opacity color hardness size') along the top, so you can connect these -- this makes mouse-based drawing far nicer, brings it up so it is not so atrociously behind the potential of tablet-based drawing
      • Option to emulate the above dynamics when stroking paths or selections -- there is not really a way to explain it, except 'try it out it's really effective!'
      • Statusbar is a lot more helpful
      • Dockable locking, which saves you from accidentally throwing your dockables out of their proper place as you whizz round the screen with your tablet.
      • Desaturate is now a tool, so it has a preview
      • Scroll beyond image borders!!! Really handy for texturing.
      • Greatly improved image scaling (code by Geert Jordaans; Visual benchmark by me)
      • Use coordinate precision that is appropriate to the tool (eg. pencil tool only cares about 1pixel granularity, so display integral coordinates)
    • inkscape 0.46:
      • Tweak tool allows to sculpt shapes and paint colors
    • Blender 2.48
      • Fluid/cloth simulation (ie softbody physics) is pretty handy for prerendering animations.. You can get some strange and wonderful effects with a little imagination, too.
      • Sculpting mode : pretty self-explanatory, hugely cool and effective.
    • Sphinx:
      • reStructured text is a really readable format that can be easily translated into HTML or PDF. Sphinx generates such HTML or PDF files from an interlinked collection of .rst files.
      • Good image support (eg specifying to display an image at 200% original size)
      • Ideally suited to Python projects, but is not locked to them only; I currently use it both for Python projects and simple miscellaneous documentation
      • Can automatically extract docstrings from Python code and combine it with your .RST docs intelligently.
    • Emacs:
      • Yeah, I found it could run under X11. It's a lot cleaner to use than XEmacs.
      • Magpie-completion is something that writers may find handy. for instance, I can type ,Mciswr then Hyper+? to get that entire segment 'Magpie-completion is something that wr' to replace ,Mciswr (Mciswr is a pattern that aforesaid text matches.)
    • AwesomeWM:
      • It is.
      • Tiling window manager, naturally.
      • Respects all my apps while actually still .. managing them, unlike Windows or most other Linux windowmanagers.
      • Minimal screen usage, as usual for tiling WMs
      • 'tagging' paradigm is pretty efficient way to work.
    • git
      • Distributed version control software. This means you do not need to be online to work on a shared project or to commit multiple revisions to it, only need to be online to finally merge the result. A server is in no way required.
      • Really easy to work with for my simple needs, far far far far far better than cvs or subversion, or even many of it's direct competitors (darcs, monotone,
      • Data for a repository is held in a single .git directory at the top level.. git doesn't need to pollute every directory with a CVS or .svn -alike directory, unlike almost every one of it's competitors.
      • It's FAST (really, really, really fast!, The fastest of it's kind.)
      • Handles binary differencing efficiently -- i was seriously considering it for tracking image painting  history, at one point.
      • Data overhead is small (*the* best, actually) (particularly if you've recently run 'git gc')
      • Linus Torvalds made it and uses it to maintain the linux kernel source tree. In terms of robustness, there could be few stronger recommendations. It's also used for version-controlling equally heavyweight things like X.Org.
    • xdelta3
      • Binary diff creator and applier.
      • second-best in my image-history benchmark, first in usability, first in robustness (has been regularly used on 2gb files!)
      • Can apply a series of binary diffs in a single operation
      • Creates only one file per binary-diff
      • If you prefer something more basic., try
    • rdiff
      • Creates two files, a checksum file and a diff-file, per binary diff. This means that..
      • You don't need the old file to create a diff.. just the checksum which is far smaller.
      • smallest binary diffs (after compression), fastest creation of binary diffs.
      • If you want to incrementally back up multiple files, rdiff-backup is a better choce
    • pylint
      • Source nitpicker, ala 'lint', except for Python.
      • Picks up on a lot of dangerous, some misleading and some just plain stupid mistakes. It's good to run it every now and then, though you probably won't agree with *all* the mistakes reported.
    • nose
      • automated unittest runner. easy, effective, even includes pdb support
      • .. and support for
    • coverage
      • investigate and report on statement coverage
      • Running your unittests and then checking the coverage is a good way to see how comprehensively your code is exercised.
    • milkyTracker
      • Linux tracking, much better than Soundtracker... what's to choose?
    Lastly, the python modules:
    • numpy
      • Anywhere you want to manipulate lots of numbers, for example a particle system, this is the module to use. Fun, effective, and extremely powerful. Flexible enough that it can be used to load arbitrary fileformats in a few lines of code.
    • scipy
      • industrial-strength applications of the above. Notably in my case, spline interpolation.
    • unittest
      • If you're not using this, why not? It's included with Python. (remember to use doctests too though!)
    • networkx
      • capable graphing module (directed and undirected graphs, with arbitrary objects as nodes.). If you need graphing, this is probably the module to go for.
    Reasonable questions happily answered. Now I'll go on to the actual personal news in the next post...
    Wednesday, January 23rd, 2008
    10:49 am
    Interactive GUI development with IPython
    I just discovered!
    IPython allows you to interactively control one of a number of GUI toolkits.
    This makes UI development *so much* easier.

    To invoke this functionality, I run IPython with the -gthread option. (I am using GTK+. For other toolkits like QT, WXWidgets, there are equivalent options (-q[4]thread, -wthread).

    So here is an example session. I started out just wanting to try it out, and then began thinking of my GIMP plugins' need to flag different types/capabilities of layers in GIMP.

    $ ipython -gthread -p sh # important! -gthread must come before all other arguments!
    
    /usr/lib/python2.6/site-packages/IPython/Extensions/path.py:32: DeprecationWarning: the md5 module is deprecated; use hashlib instead
      import sys, warnings, os, fnmatch, glob, shutil, codecs, md5
    /usr/lib/python2.6/site-packages/IPython/iplib.py:58: DeprecationWarning: the sets module is deprecated
      from sets import Set
    IPython 0.8.2   [on Py 2.6a0]
    # mistake cut.
    [~]|2> import gtk
    [~]|3> W = gtk.Window()
    # GTK main loop starts as soon as you create any GTK object(widget)
    # hence,
    # GTK initing complaints about my theme omitted here :)
    
    [~]|4> W.set_size_request(128,128)
    # I'm using the tab-completion here -- obviously the tab character isn't printed.
    
    [~]|5> gtk.Bu
    gtk.Buildable       gtk.BuilderError    gtk.ButtonAction    gtk.ButtonBoxStyle
    gtk.Builder         gtk.Button          gtk.ButtonBox       gtk.ButtonsType
    [~]|5> gtk.But
    gtk.Button          gtk.ButtonBox       gtk.ButtonsType     
    gtk.ButtonAction    gtk.ButtonBoxStyle  
    [~]|5> gtk.Button?
    # documentation I looked up is omitted. Look it up yourself :)
    # most mistakes are also omitted from here on.
    
    [~]|6> B = gtk.Button('foo')
    [~]|9> W.add(B)
    [~]|10> B.show()
    [~]|11> W.show() # the window appears, I have a single button 'foo' filling it.
    [~]|13> B.show(False) # at this point I was trying to disappear the button.
    # I eventually figured out this:
    
    [~]|15> W.remove(B)
    [~]|17> names = 'foo bar bif'
    [~]|19> buttons = [gtk.Button(name) for name in names.split()]
    [~]|21> #now make a vbox for them
    [~]|23> v = gtk.VBox()
    [~]|24> W.add(v)
    # cut out fiasco where I just was not thinking straight.
    
    [~]|30> for button in buttons:
       |..>     v.add(button)
       |..>     button.show()
       |..> 
    
    [~]|31> v.show()
    [~]|32> h = gtk.HBox()
    [~]|33> v.add(h)
    [~]|34> h.show()
    [~]|35> checks = [gtk.Check
    gtk.CheckButton    gtk.CheckMenuItem  
    [~]|35> checks = [gtk.CheckButton (name) for name in 'tiled L*a*b*-apply'.split()]
    [~]|36> for c in checks:
       |..>     h.add(c)
       |..>     c.show()
       |..> 
    [~]|37> c = checks[0]
    # toggle the state of the 'tiled' checkbox
    # Another benefit of interactive development is that I actually notice these warnings that
    # hey, that's not the smart way to do that.
    
    [~]|39> c.set_state(1) 
    /usr/bin/ipython:1: DeprecationWarning: use GtkToggleButton.set_active
      #!/usr/bin/python
    [~]|40> c.set_state(0)
    
    # Note: what I really should have done here to do the toggle should be 'c.set_active(not c.state)'
    
    [~]|49> c.get_label()
    [~]|50> c.set_active(not c.state)
    [~]|59> checks[1].grab_focus() # and give the focus to the 'L*a*b*-apply' toggle.
    


    Right now, the window looks like this:


    In combination with Ipython's logging facilities ('-log'), this is a formidable facility.
    Particularly powerful is the ability to make and debug signal handlers at runtime.

    Next: Since my GVM plugin for gimp serves as a fast plugin host, Being able to enable this threading behaviour is important to allow hosted plugins to have their own UI.
    Friday, January 18th, 2008
    10:38 pm
    new vectorscaling framework
    Yesterday, I created a specification for a fileformat and tracing process for vectorscaling.

    I was reminded of vectorscaling today, and set out to
    * Separate the tracing functionality entirely from gimp, so it only requires potrace
    * Clarify the specification
    * Implement the proper tracing of a single gray channel

    I succeeded in all of these, and also in:
    * Implement a basic working version of the fileformat
    * Implement a system to trace a multi-channel (eg RGB) image.

    Next on the tracing agenda:
    * Test/debug indexed/paletted tracing

    For the rendering, rsvg will be required.
    Depending on what tools are available, composition of the resulting image

    The fileformat is simply a zip file, with one .svg per channel.
    (eg. r.svg, g.svg, b.svg, alpha.svg)

    In the case that there is only one svg inside the zip (ie. an indexed (paletted) image or gray image, without an alpha channel)), no composition is necessary, you just render the svg.)
    Thursday, January 17th, 2008
    8:19 pm
    x OHR coding
    I was thinking about how I didn't have any time for OHR coding any more, as I was cleaning up my OHR related code in preparation to make it, in it's last incarnation, available.. and my fingers betrayed my thoughts. Instead of moving the archive of OHR-related code into an archive directory and deleting some extraneous module,
    I deleted the extraneous module, and deleted the OHR ARCHIVE!
    Fortunately, some of my OHR related work remained, and I am making that available here now.
    This includes the first and most significant of my work on translating OHRRPGCE format to YAML. (see the yaml/ directory)
    The following is the directory of the zip's content. main space is taken by test case (wander.rpg unlumped)

    directory of zipfile )

    Email me (0 0 a i 9 9 at g m a i l dot c o m) if you want it (2.3mb compressed).
    The Jormungand repository probably contains more related. I've archived that, feel free to request that too (720k). It's marginally more recent than the version in Subversion currently.

    Am currently scouring my hard disk for other OHR related code. Any contributions in the future will be of a graphical or audial nature only (eg. my new master palette; or anything where the majority of coding involved is graphics coding, and has a more general application.)

    Edit: there is a third archive of even older stuff, which includes code for reading most oldish vintage OHR formats (in C!), and the partially done QB->python translation code. (220k)
    Sunday, January 13th, 2008
    7:37 pm
    A modest proposition to achieve intelligent UI learning curves
    Hello.

    One problem I have encountered with large applications is the profusion of commands provided. I speak of applications of the functional scale of Inkscape and above. Some applications that I've had this experience with include Blender, GIMP, Emacs, and even 'simple' browsing software like Firefox. This profusion is even more extreme in commercial apps. My proposal is essentially this: to provide a way to disable UI elements, a way to package these ('novice photo editing','intermediate photo editing', 'novice pixel art', ..), a way to switch between them, and advisory dialogs coming up at startup when the number-of-days-you've-used-the-app-on passes a certain threshold.

    In GTK+, and it seems also Windows GUI, each action has a name. If each interactable UI element is registered as an action, it follows that 'domain packages', the packages of disabled-elements, can simply be textual lists naming actions to disable. It is then the job of the UI system to hide these UI elements, whether they are menu items, toolbar icons...

    Plugins: The kind of app I speak of generally has some plugin system. While the controllability of dialogs spawned by plugins is questionable, controlling registered menu items is simple. I recommend the general policy 'Don't do it'. In the other cases, you will want to disable mainly entire submenu hierarchies. For example, in GIMP, a number of blur filters are provided, that have no use for a novice pixel artist, so you want to wipe out the entire Filters/Blur menubranch.

    Finally, some actions will need to have an 'intermediate' state, where instead of hidden, they are disabled (and can be enabled by rightclick -> Enable on them; this should be a persistent part of the program state, stored in the user's homedir.). These actions are 'neighbouring' -- If you have said 'I'm a novice pixel artist', the enabled menu items should represent the set of actions that are useful to a novice pixel artist, and the greyed-out menu items should represent the set of actions that are useful in transition to intermediate pixel artist (and the hidden menu items should represent the set of items that are only useful after achieving intermediate or higher skill level.)

    Package editing should be doable by rightclick->'hide' or rightclick->'disable' on a UI element. Then you only need to provide a way to dump the current list of hidden/disabled items to a file.

    The main effort involved is in obtaining conformance (firstly, that each element has an action name. Secondly, that the ability to disable/hide/enable it is available, Thirdly, that it has realistic expectations (ie does not become baffled if it's not visible))

    An example file, for GIMP, effecting only the file menu


    #novice pixel art package
    #don't want print or email
    file-print-*
    plug-in-mail-image
    #doesn't use layers enough to need 'open as layers'
    file-open-as-layers
    #templates are a nuisance, they need a better implementation
    file-save-as-template
    # acquire only has things like screenshot and scanning; remove that menupath
    <Image>/File/Acquire
    #disable 'Open location' -- this is more the sort of thing a photomanipulator might want.
    ~file-open-location


    finally, some ramifications:
    *Mnemonics may change when switching between packages -- or rather, whether mnemonic use is ambiguous (>1 item with same mnemonic key) or not.
    *I assume menu paths are English. Of course this is not a fair assumption, instead, you should write the base language version of a menupath (often English), and then the native language version; Then auto-update the base language part according to any changes in the native language part, when loading.

    Current Mood: energetic
    Friday, July 13th, 2007
    7:40 pm
    lj-spammers?
    I don't get it. Recently I have received 3 or more ambiguous anonymous comments on this and my main journal, where a) the comment is not written in the manner of anyone I know, b) it does NOT include a URL, c) the comment is written so ambiguously it could be anybody, d) the subject is complimentary but may not make much sense in context of the journal entry, and e) the subject is not alluded to at all in the comment text.

    Actually, that's more likely to be LJer's pretending to be spammers. A sign that LJ has passed the 'critical number of members' beyond which the behaviour of the members on average declines?

    LiveJournals are not so handy, BTW. TiddlyWikis (wiki in one self-modifying HTML file) are more handy, since all your entries are stored in one file that can be worked on whereever there is a webbrowser available, and availability of individual entries/submission of new entries is not dependent on how your internet connection is feeling at the time. Personally I use the MonkeyPirate flavour (you can partly see how it works in this link: http://mptw.tiddlyspot.com/ - because that site is itself a TiddlyWiki.)
    It has a synchronize-to-web option that might assist in distributing my extremely voluminous research and notes.
    Friday, July 6th, 2007
    5:56 pm
    How to disable font antialiasing completely on Linux
    Antialiasing is not readable. It looks lush rather than crisp, so it should be used only in image editing, and for very large sizes of font (ie. for aesthetic effect only)

    I used the following method to globally disable font antialiasing (I'm running Ubuntu 6.06):

    Create the file .fonts.conf in your home directory.
    Include the following content:

    <match target="font">
        <edit mode="assign" name="antialias">
            <bool>false</bool>
        </edit>
    </match>
    


    This takes effect immediately; all applications started after this will have sharp fonts. Programs like GIMP that sometimes explicitly request antialiasing will get it (so text rendered onto the image can still be antialiased, at your option, but GIMP's UI is rendered sharply.)

    Incidentally, this will also cut down on the size of screenshots if you need to take them; proportional to amount of text onscreen, naturally.

    Screenshot:

    Thursday, June 28th, 2007
    5:06 pm
    MENU
    (With the internet being extremely cantankerous yesterday, I didn't manage to post this when I expected to.)

    Re:dmenu (http://www.suckless.org/wiki/tools/xlib)

    This is a completely brilliant piece of software. A small perfect gem!
    Why?
    * It is singleminded
    * It does what it does (selection from a menu) perfectly...
    * It grabs the attention. This is a VERY important property for menu selection (or autocompleters)
    to have, because they *are* VERY IMPORTANT whenever present. I suspect
    menus that are not (eg. say, the /Select menu in gimp).. to be bad UI design.
    * .. and it KEEPS the attention. Mouse focus can be stolen from it -- it doesn't care about
    rodents -- but it remains very visible and retains keyboard focus (ie. you can go off and
    play with your mouse while dmenu is waiting importantly for an answer, the two totally non-interfere),
    plastered across the top of the screen.
    * it doesn't let the mouse get overblown ideas of it's importance. Menus are yucky to mouse-navigate,
    and let's face it, who uses cursors while they also have a menu up?
    Making cursors THE MAIN THING for menus has always made sense, whereas mouse-menus is simply creeping featurism.
    Using the mouse to choose between menus -- MAYBE (this is like, if you have positively STACKS of menus. like gimp.)
    Using it to navigate -- no. It's a slug.. think of it like a less horrifying joystick-controlled pointer,
    when you think of menus.
    * if you just want a choice between menu items, no custom input, that works too! The user can garble
    the input if she decides she doesn't want to do any of that right now.. just delete a character or add one etc..
    pretty easy if you have a convention that say, insists on only alphanumerics..
    or they can use the command to delete the entire thing entered -- but an interface in which
    validation is as trivial as this makes the common response, when the comp. isn't doing what you want, to
    go AAAARGH and gibber-ish, to actually usually do exactly what it should -- nothing at all.
    compare this to today's hotkey-laden interfaces. Even with the undo system, you have to
    realize that you did something wrong by hitting that key, before you can fix it; you might save it
    never knowing until it's too late (you open it up in your next session)

    * without unnecessary restrictions -- you can type whatever you want
    * It's interface is similarly simple -- you just feed it newline-separated menu items on stdin, and
    it spits the choice out on stdout.
    * This is demonstrated best by how I can easily see it could just 'drop in' replace:
    * the URL bar complete with it's completion history in firefox..
    * Most entire menu HIERARCHIES! in typical modern gui programs (gimp, inkscape, potatoshop, promotion, OpenOffice.Org..)
    all these could be made SO MUCH FASTER TO USE if they'd just use a PURE MENU CONCEPT!
    * You can easily include informational options like the checkboxes/radio buttons or even
    direct values (like red = 50; the user just types red=96 to change its value)
    * It's not as effective for more complex autocompletion behaviour -- but
    you will usually find that a simpler behaviour is clearer and should be used.

    I WILL CREATE A SCREENCAST OF THE USAGE OF THIS!


    Today, I've installed an upgraded interface to my 'note' notekeeping program using dmenu.
    This is only about 6 lines of scripting, and provides the following specific advantages:
    * The old console made it equally difficult to do each command (no autocompletion, no un-requested list
    of options). The new interface makes choosing between topics extremely quick, and
    creating new topics is just as quick as it used to be.

    The source follows:


    #!/bin/sh
    NOTEBOOK=$1
    CHOICE=`note $NOTEBOOK ? | grep "[A-Z] " | cut --fields 1 -d " " | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | dmenu -p "Select page in $NOTEBOOK:> "`
    gnome-terminal -e "note $NOTEBOOK $CHOICE"

    and this script is used like

    notemenu NOTEBOOKNAME
    then you can:
    move through the menu (cursor keys, end, home, pgdn/up)
    select an option (enter)
    select no option (escape)
    select a custom option that you typed in yourself (shift-enter)
    type a string to filter options by (any printable keypress)

    this script is intended to be bound to a menu item or keyboard shortcut.
    dmenu itself 'is designed to perform well for even very large option lists (>10000)' so,
    it is also a very responsive interface.

    It does depend on Unix -- more specifically, the ability to spawn processes inexpensively is the place where dmenu properly belongs. On platforms like Windows, where spawning is expensive, piping is broken -- probably because piping's not very useful anyway without speedy process spawning -- instead, applications
    are encouraged to incorporate more and more. I'm convinced that the 'big ball of mud' development model developed exactly from the requirement to limit frequency of process spawning.

    I plan to implement a sane on-image menu system for gimp, shortly, using this. Unfortunately I cannot access all menu items via the plugin interface, but this does allow me to access most image modifications.
    Wednesday, June 27th, 2007
    1:04 am
    MENU-DRIVEN APPS MUST TAKE OVER THE WORLD!
    MORE ON THIS, AND THE PERFECT CONCEPT AND LUCID IMPLEMENTATION THAT IS DMENU, TOMORROW!

    (you know that a program is written right when you encounter it, try it and immediately jump through the ceiling shouting YES! THAT IS THE WAY IT SHOULD BE! EXACTLY AND PRECISELY! THIS PROGRAM CAN HAVE NO PEER!)

    Current Mood: world-beating
    Sunday, June 10th, 2007
    7:12 pm
    A moment of applause for test cases!
    I want to take this moment to recognize the writing and subsequent running of test cases as a supremely effective way of learning. In the software arena, you should do this for any libraries that you use, not only your self-created ones. In this way, you collect all your assumptions about the way each of these behaves together, and in conjunction with an automated test-runner such as 'nose' (introduction, homepage) you can easily identify where your premises are faulty, as it's no imposition to run your test suite once daily; and individual or package-wide testing is just as easy to invoke.

    The importance of this is to be made astoundingly clear: In the depths of a software program, while it's running, is not a reliable place to test assumptions. Firstly it is difficult to track: anyone who has seriously programmed has encountered a 'symptomatic problem' where a crash in an unrelated part of the code was caused by a mistaken operation earlier. Secondly it is simply unclear: software programs are rife with assumptions, and tests should not be subject to tangles between themselves -- each should be a simple, perfect gem of expression -- 'THIS is what should happen, and why.'

    Isolation of assumptions into a neat list like this addresses both of the above, and is very satisfying, as it provides a definite testament to your learning as it progresses. It is also a clear way of saying what your intentions and attitudes are with a particular component -- it assists cooperation between programmers in this way. See the following quote,
    of the beginning 'numpy/utilfuncs.txt' doctest (a doctest is a simple way of mixing text and python commands -- a wonderful way to both test and explain things.)

    -cut here-
    
    NUMPY UTILITY FUNCTIONS
    
    >>> from numpy import *
    
    Coverage:
        Subjects:
    	tiling
    	interpolation
    	color blends
    	palette optimization
    	colorspace conversion
    
        Functions:
    	atleast_2d
    	column_stack
    	interp
    	split
    	swapaxes
    	tile
    	tril
    	triu
    	
    
    
    
    ....................................................
    ||||||||||||||||||||||||||||||||||||||||||||||||||||
    vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
    
    interp() is a function very useful in the graphics arena.. you can use it to create blends between
    different colors, or scale up images. You can use it to warp between path shapes -- for animation.
    
    "Return the value of a piecewise-linear function at each value in x." -- help (interp)
    
    Say you have a function f -- then fp[0] should equal f(xp[0]), fp[1] == f(xp[1]),.....
    thus, 
    
    
    >>> xreqs = [-1, 0.25, 0.33, 0.66, 0.75, 1.5, 90.0]
    >>> xp = [0.0, 1.0, 2.0]
    >>> fp = [10, 20, 30]
    >>> interp (xreqs, xp, fp, -1024, 1024)
    array([-1024. ,    12.5,    13.3,    16.6,    17.5,    25. ,  1024. ])
    
    You can see it does linear interpolation (25.0 is halfway between 20 and 30, and may be found therefore at point 1.5).
    It also returns default values when values of x are requested beyond the defined range 
    ([0.0..2.0] in this case) -- if you don't specify defaults, (I gave -1024, 1024) 
    then it simply clips to the nearest defined point -- thus:
    
    >>> interp ([-1, 4], xp, fp)
    array([ 10.,  30.])
    
    >>> interp ([-345, 434], xp, fp)
    array([ 10.,  30.])
    
    
    
    
    
    'triu' slices off the N diagonal lines below a certain point. It's a good image transition effect; you must 
    know that empties become 0.
    You can only apply it to a 2d array.
    
    >>> ar = array ( [[0,1,2,3,4],[1,0,1,2,3],[2,1,0,1,2],[3,2,1,0,-1]])
    >>> triu (ar, 0)
    array([[ 0,  1,  2,  3,  4],
           [ 0,  0,  1,  2,  3],
           [ 0,  0,  0,  1,  2],
           [ 0,  0,  0,  0, -1]])
    
    >>> triu (ar, 2)
    array([[0, 0, 2, 3, 4],
           [0, 0, 0, 2, 3],
           [0, 0, 0, 0, 2],
           [0, 0, 0, 0, 0]])
    
    >>> triu (ar, -1)
    array([[ 0,  1,  2,  3,  4],
           [ 1,  0,  1,  2,  3],
           [ 0,  1,  0,  1,  2],
           [ 0,  0,  1,  0, -1]])
    
    tril performs the opposite function: it slices off the diagonal lines ABOVE a certain point.
    
    >>> tril (ar, -1)
    array([[0, 0, 0, 0, 0],
           [1, 0, 0, 0, 0],
           [2, 1, 0, 0, 0],
           [3, 2, 1, 0, 0]])
    
    tile() is quite straightforward; running 'help("numpy.tile")' explains it quite adequately. It's convenient
    for dithermatrix/screentone manipulation as well as typical tiling; you could implement gimp's 
    'small tiles' filter rather easily using it in combination with take() -- generate the 4 possible 
    flips in full size, then take the subtiles as appropriate and map them into a new array.
    
    swapaxes() just flips an array. you should perhaps be wary of array layout where you are storing pixels..
    [r,g,b],[r,g,b],[r,g,b] is the correct format for a line, rather than planar [r,r,r,r,r],[g,g,g,g,g],[b,b,b,b,b]..
    -- that is, the array should be shaped [w,h,3] or [h,w,3]. (planar is interesting too, but you better 
    use slicing for that -- else tranformations turn RGB values into BGR values or worse.
    
    split() is something like the opposite of tile():
    
    >>> t = split (array (range (16)), 4)
    >>> t
    [array([0, 1, 2, 3]), array([4, 5, 6, 7]), array([ 8,  9, 10, 11]), array([12, 13, 14, 15])]
    
    I would prefer the output in the format of a single array in this case. I do that using atleast_2d:
    
    
    >>> t3 = atleast_2d(t)  
    >>> t3
    array([[ 0,  1,  2,  3],
           [ 4,  5,  6,  7],
           [ 8,  9, 10, 11],
           [12, 13, 14, 15]])
    
    You can also stack them other ways -- see the *stack family of functions.
    
    >>> t4 = column_stack(t) 
    >>> t4
    array([[ 0,  4,  8, 12],
           [ 1,  5,  9, 13],
           [ 2,  6, 10, 14],
           [ 3,  7, 11, 15]])
    
    
    You can un-split like this:
    >>> t2 = concatenate(t)
    >>> t2
    array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15])
    
    
    bincount() helps for implementing weighted palette optimization;
    if x is an input image, you can specify the weight for each position p in image; thus you can lasso
    important areas and generate an optimized palette based on that.
    
    L*a*b <-> RGB conversion can probably be implemented much faster using matrices and arrays.
    
    bookmark: setxor
    
    

    -cut here-
    Wednesday, March 21st, 2007
    4:11 pm
    A valuable thing to place on any popular website:
    I just found this:

    http://english-88137522019.spampoison.com/

    Generates unique, non-repeating, loooooooong sequence of fake email addresses on spammers domains, rendering lists of email addresses harvested by web-spiders virtually useless.

    A useful (and simple) defense.
    Sunday, January 28th, 2007
    12:42 am
    /tmp <3
    It's sooo useful to be able to just dump things in /tmp, when a software upgrade or installation unleashes a chain of dependencies - or i want to look at something that could turn out to be irrelevant, with the assurance that these files will be gone next reboot. By default Firefox saves onto the desktop on both Windows and Linux. It's good to only save stuff permanently when you're sure you will want to keep it, esp. to counter a overcautious collection habit.
    Much love for automation -- it's cool things like this that make the process of doing things so much easier. Too much in software systems design the designer decides some part should behave in a stupid flexible way rather than a intelligent predictable way.
    Simple automations help invention -- if, when you put things in X location, they are processed in Y way, that's better than a functional (and maybe better than a object-oriented) approach -- humans find it easy to say 'A is here' 'B is there' it just happens, right? if you are standing in quicksand you will sink. A functional model is more like thinking -- X then Y then Z -- it's like having a series of thoughts.
    Fairly laborious. Object-oriented is closer to human mindset, but environments are imperative -- when you put something in a dusty environment, dust showers it and collects. This is the kind of model that's good for transforming things; it is exemplified by a directed acyclic graph (DAG) such as those handled by GEGL (http://www.gegl.org)

    uploading this as it has merit; tomorrow will allow me to see what merit that is.
    Friday, January 26th, 2007
    12:54 pm
    ziparchive module
    https://svn.sourceforge.net/svnroot/ziparchive/ziparchive/trunk

    Python has a standard module 'zipfile' which provides basic zipfile manipulation.
    Ziparchive provides a new API that addresses holes in the zipfile API --
    Support for bzip2 (de)compression
    Support for removing files stored in zip files
    file-like object API for ZIP archive members
    Support for traditional PKWARE encryption
    With the middle two, zipfiles become far more suitable as a resource packaging system for games. The last is nice too (password-protection). The file-like API also facilitates patching.

    My habitual statistics gathering -- There is an average 118.3 byte overhead per archive member. That's 118.3k per 1024 items. At an average size of 1024 bytes per item, that's
    11% overhead; For an average size of 8k, thats 1.5% overhead per item; For an average size of 64k, that's .1% overhead per item. And some additional overhead depending directly on the length of names (ie. an 8-character name in means 8 additional bytes out.)
    Thursday, December 21st, 2006
    6:49 pm
    The virtues of Ion3
    csant(?) explains the joys of Ion3:
    http://my.opera.com/csant/blog/show.dml/359494#comments

    The aspects he describes, are what prompted me to keep on using it initially.
    You don't have to manage windows, they do the right thing automatically, you don't need to poke, push, spindle, or mutilate them to obtain cooperation.
    And, you don't need a rodent to achieve things.

    Now, I like it more for its sheer ability to cooperate. For instance, I wanted to be able to warp to different GIMP windows via the keyboard (warp -> teleport mouse cursor to be on that window.) I added 10 lines of code, and it is done; I can press Hyper-Z to jump to tool options, Hyper-V to jump to paths, Hyper-S to jump to layers..
    (these keys are located immediately adjacent to Hyper)
    Other points:
    * The mouse and keyboard bindings are completely customizable. You are never stuck with dumb bindings that ill cooperate with your keyboard layout.
    * The 'workspace' concept is extremely well implemented.. you get entire separation of work flow - anything not on this workspace is not visible, so if you have two tasks, you can work on them separately without distraction.
    * Floating splits. With tile-based window management, these are extremely handy.
    they are like a normal split, except that their location depends on which frame you are in -- This allows you to set both frames as large as you'd like, and when your mouse is in one frame, the split will move to enlarge the frame to the size set for it.
    For anything that has many palettes, this can be used to hide them away in a small space while still being able to access their full contents with only a mouse movement.

    * The ability to enforce certain policies on particular windows or apps; for instance, to force a transient window to behave like a normal window, to enforce a particular size or target frame, to rewrite excessively long titles..
    Tuesday, December 19th, 2006
    10:03 am
    GVM macros
    Hello, in my last entry I used a trick to get an pixel-exact outline of a sprite. The sprite was my own remake of Bub, made for http://bub-n-bros.sf.net
    (along with a whole lot of other graphics.)
    The trick is:
    Feather the selection by 2
    Threshold the selection mask to the range (8..105) -- that selects everything that is immediately (as in, U D L R, not diagonal) adjacent to the current selection, and deselects all else.. (because threshold makes whatever is inside the range white == selected, all else black == deselected)

    Which gave me an almost perfect result -- I remembered how I'd done this before.
    Then I noticed a stray pixel, and finetuned my process: in fact, a better range is 15..105, which eliminated the stray pixel.

    So, I quickly chucked it into the same file as my trivial fillfg() example, added it to the list of macros to register at the top of the file, hit refresh, and.. it works first time! This is exactly what I made the GVM engine for!


    Current contents of colorfill.py
    #GVM
    #fillrandpalcol
    #seloutline
    
    
    # it is expected that the wrapper for this will accept 
    # run_mode, image, drawable
    #
    # the function shall be registered as 
    # gvm_fillfg
    #
    # all macro functions should begin with a _
    # the wrapper will be fully qualified:
    #   gvm_fillfg
    #
    def _fillrandpalcol (drawable):
        """QUICK/Fill with ran_dom Palette color
        Fill the selected region with a random color from the palette"""
        from ai.gimp.color.palette import Palette
        from random import randint
        fg = gimp.get_foreground()
        p = Palette()
        color = p[randint(0,len (p))]
        gimp.set_foreground (color)
        pdb.gimp_edit_fill (drawable, FOREGROUND_FILL)
        gimp.set_foreground (fg)
        flushDisplays()
    
    def _seloutline (image, drawable):
        """<Image>/Selection/E_xact Outline
        Outline the selection by EXACTLY 1 pixel.
        FUTURE VARIANT: Smooth Exact Outline --
            applies 'Curves' to achieve:
                int. 255 @ ((14 + 105) / 2) 
                int. 0 @ 0
                int. 0 @ 255
            # could 'sharpen' be used so I'd only need one version?
        """
        sel = image.selection
        pdb.gimp_selection_feather (image, 2.0)
        pdb.gimp_threshold (sel, 14, 105)
    
    


    eeheehehehehe.
    BTW, as far as I know, the GVM engine is fully Windows compatible; although it currently hardcodes the path to find macros in, that could be fixed. I'll try it later. Some of my other plugins were not working on Windows because of making API changes and not updating all plugins to match. I think all plugins that are working on my system should work on Windows now.
    HURRAH!
    10:03 am
    GVM progress
    I'm way too obsessed with knowing the most efficient way to do things, anyone who knows me will agree. So I went and implemented a simple parser for the embedded metadata in GVM macros, rather than try to optimize the engine. After one exceedingly silly bugfix,
    It detects all my macros' data okay:

    RESULTS : {'/home/ai/gimp/macros/shift.py': [('shift', 'varshift', ['up', 'down', 'left', 'right', 'ul', 'ur', 'dl', 'dr', 'upx', 'downx', 'leftx', 'rightx', 'ulx', 'urx', 'dlx', 'drx']), ('tesselation_test', None, None)], ('tesselation_test', None, None)], '/home/ai/gimp/macros/flatten_frames.py': None, '/home/ai/gimp/macros/colorfill.py': [('fillfg', None, None)]}

    -- note - flatten_frames is not in GVM format yet, so it correctly detected nothing
    -- note2 - shift is a macro with variants. Its data says 'indirect all calls to shift() via varshift(), appending an index value (0=up, 1=down, 2=left....)'. So varshift (image, drawable) does some calculations (making movement amounts proportional to the scale of your image) and then calls shift() with the calculated values.
    -- note3 - fillfg is a complete, theoretically working macro written in 4 lines plus 1 line of header.

    UPDATE:
    my prototype, fillfg, is WORKING!!!

    code:

    #GVM
    #fillfg
    
    #
    # the function shall be registered as 
    # gvm_fillfg
    #
    # all macro functions should begin with a _
    # the wrapper will be fully qualified:
    #   gvm_fillfg
    #
    def _fillfg (drawable):
        """QUICK/fillfg
        Trivial macro to fill the drawable with fg color"""
        pdb.gimp_edit_fill (drawable, FOREGROUND_FILL)
        flushDisplays()
    
    


    Note -- this just wraps an existing function, it doesn't actually do anything new. I plan to move my color-editing commands into macros next, where they can be many times faster and more featureful. I've already implemented macro refreshing in GVM -- this makes it easy to revise a macro and test it quickly, or even to add macros during a single GIMP session -- which is something very helpful that plugins cannot do.

    ye for now.
    Saturday, December 16th, 2006
    12:39 pm
    How to install GIMP on windows with Python support!
    Just now, I've got a Python console up, and all the standard Python plugins show up in the menus, under Windows.
    I've been trying to achieve this for more than a year, and it's finally done!
    Thanks to jernej, the maintainer of the GIMP binary installers for Windows.


    First remove any existing versions of gtk+, gimp, pycairo, pygtk+ and numpy from the computer. Remove any existing versions of Python, too, whether that is the Python distribution from www.python.org, or ActiveState Python.


    Download from these URLs:

    http://www.activestate.com/Products/ActivePython/ (select version 2.4 or later)

    http://sourceforge.net/project/showfiles.php?group_id=121075
    (GIMP) click 'Download' then 'gimp-2.3.12-i586-setup.zip'
    (GTK) click 'Download' then 'gtk+-2.10.6-1-setup.zip'
    Both of these are zips containing a single installer .EXE.

    http://www.mapr.ucl.ac.be/~gustin/win32_ports/
    in the 'Python 2.4' division in the 'pygtk 2.8', download both files.

    http://sourceforge.net/project/showfiles.php?group_id=1369
    download Numpy (numpy-1.0.1.win32-py2.4.exe)

    And install. I installed in this order:

    ActiveState Python
    NumPy
    GTK+
    PyCairo
    PyGTK+
    GIMP (verify that the 'gimp-python' extension is checked)

    The first thing you should do after installing is open GIMP, go to the toolbox, and select 'Xtns->Python-Fu->Console' from the toolbox menu. This should bring up a window titled 'Python Console'. Now load an image.
    Enter the following into the console:

    i = gimp.image_list()[0]
    print i
    


    It should print out something like "<gimp.Image 'mypic.png'>". If this works, then your PyGimp installation is in good shape!


    (this is not my windows system; It is just the one I tried this on.)

    PART 1 COMPLETE.
    PART 2 deals with installing my PyGimp plugins (of which there are many)
[ << Previous 20 ]
main journal   About LiveJournal.com

Advertisement