Here you can find the source of a plug-in written in C for GIMP. It works as a Gimp filter that transforms any bitmap image (RGB) into the closest image in the ZX Spectrum screen format. Welcome back ZX-look!
I have written other software related to the ZX Spectrum, such as the Nutria emulator and the ZX Ecosystem library for writing ZX-like programs for modern computers in C++ (which, in fact, uses the same algorithm of this plug-in for loading PNG files into the ZX screen format).
This plug-in requires an RGB bitmap (I have not tested it, but it should work on images with transparency too). The resolution does not matter, although for obtaining an experience that is close to what a real ZX Spectrum would do, it is convenient to scale it down to a width of 256 pixels (the height can be any) before applying the filter. The plug-in installs itself in a new filter submenu of Gimp called "ZX", and it does not require any parameter for execution. Filtering is carried out directly on the image, using a colour palette that I have checked is pretty similar to the ZX original one (I have tested it on snapshots taken from ZX Spectrum emulators and there is no appreciable change in the colours).
The algorithm is a little tricky, since some decisions must be made when reducing the colour map of the original image (please consult this link for background information on the ZX Spectrum screen system). The process is as follows. Every 8x8 pixel cell in the original image is treated separately (pixels of the original image that fall outside any whole cell will be set to black directly). Within each 8x8 cell, the colours of the ZX palette, including those with bright and those without bright, that correspond to the pixels of the original image are calculated using the cartesian distance in the 3D space of RGB coordinates of colours. After this mapping, a histogram of the ZX colours used is made up to see which one is most frequent in that cell, and which one is the second most frequent. The former will be the "ink" colour, while the latter will be the "paper" colour. All the pixels in the cell that are not ink or paper will be changed by the closest of these two in the RGB euclidean space. Finally, the decision on the bright of the cell is to be made (the flash attribute is not dealt with): if both (ink,paper) colours of the cell have the same bright, nothing special is needed; otherwise, one of them must be changed to match the bright attribute of the other, since there is only one bright attribute for the entire cell in the ZX screen; if one of them is the black color, that one will be changed, because changes in the bright of black leave that colour unaltered; if no colour is black, then the one less frequent in the cell (i.e., the paper colour) will be changed to match the bright of the other (i.e., the ink). And voilà :)
Here I leave some examples of what you can expect to achieve with this plug-in. You can use Ctrl+ several times to appreciate the details better.
In this link you can download the source code of the plug-in. I have not been very careful or elegant concerning the code quality (although it is pretty documented). To install it in a Linux machine you just have to install previously the development package of Gimp (libgimp-dev typically) and then use the "gimptool-2.0" in the comand line as it is explained in the very source code of the plug-in.
Since this code has been just a short exercise, no further maintenance or development is expected by now.
The ZX Gimp plug-in has been developed by me (Juan-Antonio Fernández-Madrigal) in July 2011 building it from the example "blur plug-in" by David Neary. It is easy to write plug-ins for GIMP, specially in Linux systems (GIMP has versions also for other OSes) if you know C. You can find here a tutorial that proves how straightforward to use is the API of GIMP: it provides you with an execution environment quite complete where you can handle the currently opened image.
If you are interested in contacting me, you can use "jafmag" (remove quotes) at gmail.