# imaging package¶

## imaging.images2avi module¶

Module images2avi

Uses ffmpeg to read and write AVI files. Requires PIL

I found these sites useful: http://www.catswhocode.com/blog/19-ffmpeg-commands-for-all-needs http://linux.die.net/man/1/ffmpeg

Read images from an AVI (or MPG) movie.

Requires the “ffmpeg” application:
• Most linux users can install using their package manager
• There is a windows installer on the visvis website
Parameters: filename (str) – name of input movie file asNumpy (bool) –
imaging.images2avi.writeAvi(filename, images, duration=0.1, encoding='mpeg4', inputOptions='', outputOptions='')[source]

Export movie to a AVI file, which is encoded with the given encoding. Hint for Windows users: the ‘msmpeg4v2’ codec is natively supported on Windows.

Images should be a list consisting of PIL images or numpy arrays. The latter should be between 0 and 255 for integer types, and between 0 and 1 for float types.

Requires the “ffmpeg” application:
• Most linux users can install using their package manager
• There is a windows installer on the visvis website
Parameters: filename (str) – output filename images – duration (float) – encoding (str) – the encoding type inputOptions – outputOptions –

## imaging.images2gif module¶

Module images2gif

Provides functionality for reading and writing animated GIF images. Use writeGif to write a series of numpy arrays or PIL images as an animated GIF. Use readGif to read an animated gif as a series of numpy arrays.

Note that since July 2004, all patents on the LZW compression patent have expired. Therefore the GIF format may now be used freely.

Acknowledgements:

Many thanks to Ant1 for:

• noting the use of “palette=PIL.Image.ADAPTIVE”, which significantly improves the results.
• the modifications to save each image with its own palette, or optionally the global palette (if its the same).

Many thanks to Marius van Voorden for porting the NeuQuant quantization algorithm of Anthony Dekker to Python (See the NeuQuant class for its license).

Many thanks to Alex Robinson for implementing the concept of subrectangles, which (depening on image content) can give a very significant reduction in file size.

This code is based on gifmaker (in the scripts folder of the source distribution of PIL)

class imaging.images2gif.GifWriter[source]

Class that contains methods for helping write the animated GIF file.

convertImagesToPIL(images, nq=0)[source]

Convert images to Paletted PIL images, which can then be written to a single animaged GIF.

getAppExt(loops=inf)[source]

Application extension. This part specifies the amount of loops. If loops is 0 or inf, it goes on infinitely.

Parameters: loops (float) –
getGraphicsControlExt(duration=0.1, dispose=2)[source]

Graphics Control Extension. A sort of header at the start of each image. Specifies duration and transparency.

Dispose:

• 0 - No disposal specified.
• 1 - Do not dispose. The graphic is to be left in place.
• 2 - Restore to background color. The area used by the graphic must be restored to the background color.
• 3 - Restore to previous. The decoder is required to restore the area overwritten by the graphic with what was there prior to rendering the graphic.
• 4-7 -To be defined.
Parameters: duration (double) – dispose –
getImageDescriptor(im, xy=None)[source]

Used for the local color table properties per image. Otherwise global color table applies to all frames irrespective of whether additional colors comes in play that require a redefined palette. Still a maximum of 256 color per frame, obviously.

Written by Ant1 on 2010-08-22 Modified by Alex Robinson in Janurari 2011 to implement subrectangles.

Parameters: im – xy –
getSubRectangles(ims)[source]

Calculate the minimal rectangles that need updating each frame. Returns a two-element tuple containing the cropped images and a list of x-y positions.

Calculating the subrectangles takes extra time, obviously. However, if the image sizes were reduced, the actual writing of the GIF goes faster. In some cases applying this method produces a GIF faster.

Parameters: im –
handleSubRectangles(images, subRectangles)[source]

Handle the sub-rectangle stuff. If the rectangles are given by the user, the values are checked. Otherwise the subrectangles are calculated automatically.

writeGifToFile(fp, images, durations, loops, xys, disposes)[source]

Given a set of images writes the bytes to the specified stream. Requires different handling of palette for PIL and Pillow: based on https://github.com/rec/echomesh/blob/master/ code/python/external/images2gif.py

class imaging.images2gif.NeuQuant(image, samplefac=10, colors=256)[source]

NeuQuant(image, samplefac=10, colors=256)

samplefac should be an integer number of 1 or higher, 1 being the highest quality, but the slowest performance. With avalue of 10, one tenth of all pixels are used during training. This value seems a nice tradeof between speed and quality.

colors is the amount of colors to reduce the image to. This should best be a power of two.

License of the NeuQuant Neural-Net Quantization Algorithm

Copyright (c) 1994 Anthony Dekker Ported to python by Marius van Voorden in 2010

NEUQUANT Neural-Net quantization algorithm by Anthony Dekker, 1994. See “Kohonen neural networks for optimal colour quantization” in “network: Computation in Neural Systems” Vol. 5 (1994) pp 351-367. for a discussion of the algorithm. See also http://members.ozemail.com.au/~dekker/NEUQUANT.HTML

Any party obtaining a copy of these files from the author, directly or indirectly, is granted, free of charge, a full and unrestricted irrevocable, world-wide, paid up, royalty-free, nonexclusive right and license to deal in this software and documentation files (the “Software”), including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons who receive copies from any such party to do so, with the only requirement being that this copyright notice remain intact.

ALPHABIASSHIFT = None
BETA = None
BETAGAMMA = None
BGCOLOR = None
CUTNETSIZE = None
GAMMA = None
INITALPHA = None
MAXNETPOS = None
MAXPRIME = 503
NCYCLES = None
NETSIZE = None
PRIME1 = 499
PRIME2 = 491
PRIME3 = 487
PRIME4 = 503
SPECIALS = None
a_s = None
alterneigh(alpha, rad, i, b, g, r)[source]
altersingle(alpha, i, b, g, r)[source]

Move neuron i towards biased (b, g, r) by factor alpha

bias = None
colormap = None
contest(b, g, r)[source]

Search for biased BGR values Finds closest neuron (min dist) and updates self.freq finds best neuron (min dist-self.bias) and returns position for frequently chosen neurons, self.freq[i] is high and self.bias[i] is negative self.bias[i] = self.GAMMA * ((1/self.NETSIZE)-self.freq[i])

convert(*color)[source]
fix()[source]
freq = None
inxbuild()[source]
inxsearch(r, g, b)[source]

Search for BGR values 0..255 and return colour index

learn()[source]
netindex = None
network = None
paletteImage()[source]

PIL weird interface for making a paletted image: create an image which already has the palette, and use that in Image.quantize. This function returns this palette image.

pimage = None
pixels = None
quantize(image)[source]

Use a kdtree to quickly find the closest palette colors for the pixels

Parameters: image –
quantize_with_scipy(image)[source]
quantize_without_scipy(image)[source]

” This function can be used if no scipy is available. It’s 7 times slower though.

Parameters: image –
samplefac = None
setUpArrays()[source]
setconstants(samplefac, colors)[source]
specialFind(b, g, r)[source]
writeColourMap(rgb, outstream)[source]
imaging.images2gif.checkImages(images)[source]

Check numpy images and correct intensity range etc. The same for all movie formats.

Parameters: images –
imaging.images2gif.get_cKDTree()[source]
imaging.images2gif.intToBin(i)[source]

Integer to two bytes

Read images from an animated GIF file. Returns a list of numpy arrays, or, if asNumpy is false, a list if PIL images.

imaging.images2gif.writeGif(filename, images, duration=0.1, repeat=True, **kwargs)[source]

Write an animated gif from the specified images. Depending on which PIL library is used, either writeGifVisvis or writeGifPillow is used here.

Parameters: filename (str) – the name of the file to write the image to. images (list) – should be a list consisting of PIL images or numpy arrays. The latter should be between 0 and 255 for integer types, and between 0 and 1 for float types. duration – scalar or list of scalars The duration for all frames, or (if a list) for each frame. repeat – bool or integer The amount of loops. If True, loops infinitetel kwargs – additional parameters for writeGifVisvis
imaging.images2gif.writeGifPillow(filename, images, duration=0.1, repeat=True)[source]

Write an animated gif from the specified images. Uses native Pillow implementation, which is available since Pillow 3.4.0.

Parameters: filename (str) – the name of the file to write the image to. images (list) – should be a list consisting of PIL images or numpy arrays. The latter should be between 0 and 255 for integer types, and between 0 and 1 for float types. duration – scalar or list of scalars The duration for all frames, or (if a list) for each frame. repeat – bool or integer The amount of loops. If True, loops infinitetel
imaging.images2gif.writeGifVisvis(filename, images, duration=0.1, repeat=True, dither=False, nq=0, subRectangles=True, dispose=None)[source]

Write an animated gif from the specified images. Uses VisVis implementation. Unfortunately it produces corrupted GIF with Pillow >= 3.4.0.

Parameters: filename (str) – the name of the file to write the image to. images (list) – should be a list consisting of PIL images or numpy arrays. The latter should be between 0 and 255 for integer types, and between 0 and 1 for float types. duration – scalar or list of scalars The duration for all frames, or (if a list) for each frame. repeat – bool or integer The amount of loops. If True, loops infinitetely. dither (bool) – whether to apply dithering nq (int) – If nonzero, applies the NeuQuant quantization algorithm to create the color palette. This algorithm is superior, but slower than the standard PIL algorithm. The value of nq is the quality parameter. 1 represents the best quality. 10 is in general a good tradeoff between quality and speed. When using this option, better results are usually obtained when subRectangles is False. subRectangles – False, True, or a list of 2-element tuples Whether to use sub-rectangles. If True, the minimal rectangle that is required to update each frame is automatically detected. This can give significant reductions in file size, particularly if only a part of the image changes. One can also give a list of x-y coordinates if you want to do the cropping yourself. The default is True. dispose (int) – how to dispose each frame. 1 means that each frame is to be left in place. 2 means the background color should be restored after each frame. 3 means the decoder should restore the previous frame. If subRectangles==False, the default is 2, otherwise it is 1.

## imaging.images2ims module¶

Module images2ims

Use PIL to create a series of images.

imaging.images2ims.checkImages(images)[source]

Check numpy images and correct intensity range etc. The same for all movie formats.

Parameters: images –

Read images from a series of images in a single directory. Returns a list of numpy arrays, or, if asNumpy is false, a list if PIL images.

Parameters: filename – asNumpy (bool) –
imaging.images2ims.writeIms(filename, images)[source]

Export movie to a series of image files. If the filenenumber contains an asterix, a sequence number is introduced at its location. Otherwise the sequence number is introduced right before the final dot.

To enable easy creation of a new directory with image files, it is made sure that the full path exists.

Images should be a list consisting of PIL images or numpy arrays. The latter should be between 0 and 255 for integer types, and between 0 and 1 for float types.

Parameters: filename – images –

## imaging.images2swf module¶

Module images2swf

Provides a function (writeSwf) to store a series of PIL images or numpy arrays in an SWF movie, that can be played on a wide range of OS’s.

This module came into being because I wanted to store a series of images in a movie that can be viewed by other people, and which I can embed in flash presentations. For writing AVI or MPEG you really need a c/c++ library, and although the filesize is then very small, the quality is sometimes not adequate. Besides I’d like to be independent of yet another package. I tried writing animated gif using PIL (which is widely available), but the quality is so poor because it only allows for 256 different colors. [EDIT: thanks to Ant1, now the quality of animated gif isn’t so bad!] I also looked into MNG and APNG, two standards similar to the PNG stanard. Both standards promise exactly what I need. However, hardly any application can read those formats, and I cannot import them in flash.

Therefore I decided to check out the swf file format, which is very well documented. This is the result: a pure python module to create an SWF file that shows a series of images. The images are stored using the DEFLATE algorithm (same as PNG and ZIP and which is included in the standard Python distribution). As this compression algorithm is much more effective than that used in GIF images, we obtain better quality (24 bit colors + alpha channel) while still producesing smaller files (a test showed ~75%). Although SWF also allows for JPEG compression, doing so would probably require a third party library (because encoding JPEG is much harder).

This module requires Python 2.x and numpy.

sources and tools:

• SWF on wikipedia
• swftools (swfdump in specific) for debugging
• iwisoft swf2avi can be used to convert swf to avi/mpg/flv with really good quality, while file size is reduced with factors 20-100. A good program in my opinion. The free version has the limitation of a watermark in the upper left corner.
class imaging.images2swf.BitArray(initvalue=None)[source]

Dynamic array of bits that automatically resizes with factors of two. Append bits using .Append() or += You can reverse bits using .Reverse()

Append(bits)[source]
Reverse()[source]

In-place reverse.

ToBytes()[source]

Convert to bytes. If necessary, zeros are padded to the end (right side).

class imaging.images2swf.BitmapTag(im)[source]
ProcessTag()[source]
class imaging.images2swf.ControlTag[source]

Bases: imaging.images2swf.Tag

class imaging.images2swf.DefinitionTag[source]

Bases: imaging.images2swf.Tag

counter = 0
class imaging.images2swf.DoActionTag(action='stop')[source]

Bases: imaging.images2swf.Tag

Append(action)[source]
ProcessTag()[source]
class imaging.images2swf.FileAttributesTag[source]
ProcessTag()[source]
class imaging.images2swf.PlaceObjectTag(depth, idToPlace=None, xy=(0, 0), move=False)[source]
ProcessTag()[source]
class imaging.images2swf.SetBackgroundTag(*rgb)[source]

Set the color in 0-255, or 0-1 (if floats given).

ProcessTag()[source]
class imaging.images2swf.ShapeTag(bitmapId, xy, wh)[source]
MakeEndShapeRecord()[source]
MakeStraightEdgeRecord(*dxdy)[source]
MakeStyleChangeRecord(lineStyle=None, fillStyle=None, moveTo=None)[source]
ProcessTag()[source]

Returns a defineshape tag. with a bitmap fill

class imaging.images2swf.ShowFrameTag[source]
ProcessTag()[source]
class imaging.images2swf.Tag[source]
GetTag()[source]

Calls processTag and attaches the header.

MakeMatrixRecord(scale_xy=None, rot_xy=None, trans_xy=None)[source]
MakeRectRecord(xmin, xmax, ymin, ymax)[source]

Simply uses makeCompactArray to produce a RECT Record.

ProcessTag()[source]

Implement this to create the tag.

imaging.images2swf.bitsToInt(bb, n=8)[source]
imaging.images2swf.buildFile(fp, taglist, nframes=1, framesize=(500, 500), fps=10, version=8)[source]

Give the given file (as bytes) a header.

imaging.images2swf.checkImages(images)[source]

Check numpy images and correct intensity range etc. The same for all movie formats.

imaging.images2swf.floatsToBits(arr)[source]

Given a few (signed) numbers, convert them to bits, stored as FB (float bit values). We always use 16.16. Negative numbers are not (yet) possible, because I don’t know how the’re implemented (ambiguity).

imaging.images2swf.getTypeAndLen(bb)[source]

bb should be 6 bytes at least Return (type, length, length_of_full_tag)

imaging.images2swf.intToBits(i, n=None)[source]

convert int to a string of bits (0’s and 1’s in a string), pad to n elements. Convert back using int(ss,2).

imaging.images2swf.intToUint16(i)[source]
imaging.images2swf.intToUint32(i)[source]
imaging.images2swf.intToUint8(i)[source]

Read all images from an SWF (shockwave flash) file. Returns a list of numpy arrays, or, if asNumpy is false, a list if PIL images.

Limitation: only read the PNG encoded images (not the JPG encoded ones).

imaging.images2swf.signedIntToBits(i, n=None)[source]

convert signed int to a string of bits (0’s and 1’s in a string), pad to n elements. Negative numbers are stored in 2’s complement bit patterns, thus positive numbers always start with a 0.

imaging.images2swf.twitsToBits(arr)[source]

Given a few (signed) numbers, store them as compactly as possible in the wat specifief by the swf format. The numbers are multiplied by 20, assuming they are twits. Can be used to make the RECT record.

imaging.images2swf.writeSwf(filename, images, duration=0.1, repeat=True)[source]

Write an swf-file from the specified images. If repeat is False, the movie is finished with a stop action. Duration may also be a list with durations for each frame (note that the duration for each frame is always an integer amount of the minimum duration.)

Images should be a list consisting of PIL images or numpy arrays. The latter should be between 0 and 255 for integer types, and between 0 and 1 for float types.

## imaging.operations module¶

Image non-geospatial operations and manipulations

Note: Functions in this module are experimental and are not considered a stable API, i.e. may change in future releases of GRASS GIS.

It heavily relies on PIL but unlike PIL, the functions operate on files instead of PIL Image objects (which are used internally). These functions are convenient for post-processing outputs from GRASS modules, e.g. after rendering. However, if you have multiple operations you may want to consider using PIL directly for efficiency (to avoid writing and reading from the files).

### Usage¶

Use keyword arguments for all parameters other than those for input, output, and format. All function provide reasonable defaults if possible, but note that they may not be applicable to you case or when developing a general tool.

>>> import grass.imaging.operations as iop

>>> # replace white color in the image by 100% transparency
>>> iop.change_rbg_to_transparent("map.png", color=(255, 255, 255))

>>> # crop the image in place
>>> iop.crop_image("map.png")

>>> # create a new image with inverted colors of the original image
>>> iop.invert_image_colors("map.png", "map_inverted.png")

>>> # create a thumbnail of the original image
>>> iop.thumbnail_image("map.png", "map_thumbnail.png", size=(64, 64))


### Error handling¶

When PIL or a required submodule is not available, a RuntimeError exception is raised with a message mentioning the missing dependency. Additionally, any of the exceptions raised by PIL may be raised too, for example, when the file is not found.