Writing Your Own Image Plugin
The Pillow uses a plug-in model which allows you to add your owndecoders to the library, without any changes to the libraryitself. Such plug-ins usually have names likeXxxImagePlugin.py
, where Xxx
is a unique format name(usually an abbreviation).
警告
Pillow >= 2.1.0 no longer automatically imports any filein the Python path with a name ending inImagePlugin.py
. You will need to import yourimage plugin manually.
Pillow decodes files in 2 stages:
- It loops over the available image plugins in the loaded order, andcalls the plugin’s
accept
function with the first 16 bytes ofthe file. If theaccept
function returns true, the plugin’s_open
method is called to set up the image metadata and imagetiles. The_open
method is not for decoding the actual imagedata. - When the image data is requested, the
ImageFile.load
method iscalled, which sets up a decoder for each tile and feeds the data toit.
An image plug-in should contain a format handler derived from thePIL.ImageFile.ImageFile
base class. This class shouldprovide an_open()
method, which reads the file header andsets up at least themode
andsize
attributes. To be able to load thefile, the method must also create a list oftile
descriptors, which contain a decoder name, extents of the tile, andany decoder-specific data. The format handler class must be explicitlyregistered, via a call to theImage
module.
注解
For performance reasons, it is important that the_open()
method quickly rejects files that do not have theappropriate contents.
Example
The following plug-in supports a simple format, which has a 128-byte headerconsisting of the words “SPAM” followed by the width, height, and pixel size inbits. The header fields are separated by spaces. The image data followsdirectly after the header, and can be either bi-level, greyscale, or 24-bittrue color.
SpamImagePlugin.py:
- from PIL import Image, ImageFile
- import string
- class SpamImageFile(ImageFile.ImageFile):
- format = "SPAM"
- format_description = "Spam raster image"
- def _open(self):
- # check header
- header = self.fp.read(128)
- if header[:4] != "SPAM":
- raise SyntaxError, "not a SPAM file"
- header = string.split(header)
- # size in pixels (width, height)
- self._size = int(header[1]), int(header[2])
- # mode setting
- bits = int(header[3])
- if bits == 1:
- self.mode = "1"
- elif bits == 8:
- self.mode = "L"
- elif bits == 24:
- self.mode = "RGB"
- else:
- raise SyntaxError, "unknown number of bits"
- # data descriptor
- self.tile = [
- ("raw", (0, 0) + self.size, 128, (self.mode, 0, 1))
- ]
- Image.register_open(SpamImageFile.format, SpamImageFile)
- Image.register_extension(SpamImageFile.format, ".spam")
- Image.register_extension(SpamImageFile.format, ".spa") # dos version
The format handler must always set thesize
and mode
attributes. If these are not set, the file cannot be opened. Tosimplify the plugin, the calling code considers exceptions likeSyntaxError
, KeyError
, IndexError
,EOFError
and struct.error
as a failure to identifythe file.
Note that the image plugin must be explicitly registered usingPIL.Image.register_open()
. Although not required, it is also a goodidea to register any extensions used by this format.
The tile attribute
To be able to read the file as well as just identifying it, the tile
attribute must also be set. This attribute consists of a list of tiledescriptors, where each descriptor specifies how data should be loaded to agiven region in the image. In most cases, only a single descriptor is used,covering the full image.
The tile descriptor is a 4-tuple with the following contents:
- (decoder, region, offset, parameters)
The fields are used as follows:
- decoder
- Specifies which decoder to use. The
raw
decoder used here supportsuncompressed data, in a variety of pixel formats. For more information onthis decoder, see the description below. - region
- A 4-tuple specifying where to store data in the image.
- offset
- Byte offset from the beginning of the file to image data.
- parameters
- Parameters to the decoder. The contents of this field depends on thedecoder specified by the first field in the tile descriptor tuple. If thedecoder doesn’t need any parameters, use None for this field.
Note that the tile
attribute contains a list of tile descriptors,not just a single descriptor.
Decoders
The raw decoder
The raw
decoder is used to read uncompressed data from an image file. Itcan be used with most uncompressed file formats, such as PPM, BMP, uncompressedTIFF, and many others. To use the raw decoder with thePIL.Image.frombytes()
function, use the following syntax:
- image = Image.frombytes(
- mode, size, data, "raw",
- raw mode, stride, orientation
- )
When used in a tile descriptor, the parameter field should look like:
- (raw mode, stride, orientation)
The fields are used as follows:
- raw mode
- The pixel layout used in the file, and is used to properly convert data toPIL’s internal layout. For a summary of the available formats, see thetable below.
- stride
- The distance in bytes between two consecutive lines in the image. If 0, theimage is assumed to be packed (no padding between lines). If omitted, thestride defaults to 0.
- orientation
- Whether the first line in the image is the top line on the screen (1), orthe bottom line (-1). If omitted, the orientation defaults to 1.
The raw mode field is used to determine how the data should be unpacked tomatch PIL’s internal pixel layout. PIL supports a large set of raw modes; for acomplete list, see the table in the Unpack.c
module. The followingtable describes some commonly used raw modes:
mode | description |
---|---|
1 | 1-bit bilevel, stored with the leftmost pixel in the mostsignificant bit. 0 means black, 1 means white. |
1;I | 1-bit inverted bilevel, stored with the leftmost pixel in themost significant bit. 0 means white, 1 means black. |
1;R | 1-bit reversed bilevel, stored with the leftmost pixel in theleast significant bit. 0 means black, 1 means white. |
L | 8-bit greyscale. 0 means black, 255 means white. |
L;I | 8-bit inverted greyscale. 0 means white, 255 means black. |
P | 8-bit palette-mapped image. |
RGB | 24-bit true colour, stored as (red, green, blue). |
BGR | 24-bit true colour, stored as (blue, green, red). |
RGBX | 24-bit true colour, stored as (red, green, blue, pad). The padpixels may vary. |
RGB;L | 24-bit true colour, line interleaved (first all red pixels, thenall green pixels, finally all blue pixels). |
Note that for the most common cases, the raw mode is simply the same as the mode.
The Python Imaging Library supports many other decoders, including JPEG, PNG,and PackBits. For details, see the decode.c
source file, and thestandard plug-in implementations provided with the library.
Decoding floating point data
PIL provides some special mechanisms to allow you to load a wide variety offormats into a mode F
(floating point) image memory.
You can use the raw
decoder to read images where data is packed in anystandard machine data type, using one of the following raw modes:
mode | description |
---|---|
F | 32-bit native floating point. |
F;8 | 8-bit unsigned integer. |
F;8S | 8-bit signed integer. |
F;16 | 16-bit little endian unsigned integer. |
F;16S | 16-bit little endian signed integer. |
F;16B | 16-bit big endian unsigned integer. |
F;16BS | 16-bit big endian signed integer. |
F;16N | 16-bit native unsigned integer. |
F;16NS | 16-bit native signed integer. |
F;32 | 32-bit little endian unsigned integer. |
F;32S | 32-bit little endian signed integer. |
F;32B | 32-bit big endian unsigned integer. |
F;32BS | 32-bit big endian signed integer. |
F;32N | 32-bit native unsigned integer. |
F;32NS | 32-bit native signed integer. |
F;32F | 32-bit little endian floating point. |
F;32BF | 32-bit big endian floating point. |
F;32NF | 32-bit native floating point. |
F;64F | 64-bit little endian floating point. |
F;64BF | 64-bit big endian floating point. |
F;64NF | 64-bit native floating point. |
The bit decoder
If the raw decoder cannot handle your format, PIL also provides a special “bit”decoder that can be used to read various packed formats into a floating pointimage memory.
To use the bit decoder with the PIL.Image.frombytes()
function, usethe following syntax:
- image = Image.frombytes(
- mode, size, data, "bit",
- bits, pad, fill, sign, orientation
- )
When used in a tile descriptor, the parameter field should look like:
- (bits, pad, fill, sign, orientation)
The fields are used as follows:
- bits
- Number of bits per pixel (2-32). No default.
- pad
- Padding between lines, in bits. This is either 0 if there is no padding, or8 if lines are padded to full bytes. If omitted, the pad value defaults to8.
- fill
- Controls how data are added to, and stored from, the decoder bit buffer.
- fill=0
- Add bytes to the LSB end of the decoder buffer; store pixels from the MSBend.
- fill=1
- Add bytes to the MSB end of the decoder buffer; store pixels from the MSBend.
- fill=2
- Add bytes to the LSB end of the decoder buffer; store pixels from the LSBend.
- fill=3
- Add bytes to the MSB end of the decoder buffer; store pixels from the LSBend.
If omitted, the fill order defaults to 0.
- sign
- If non-zero, bit fields are sign extended. If zero or omitted, bit fieldsare unsigned.
- orientation
- Whether the first line in the image is the top line on the screen (1), orthe bottom line (-1). If omitted, the orientation defaults to 1.
Writing Your Own File Decoder in C
There are 3 stages in a file decoder’s lifetime:
- Setup: Pillow looks for a function in the decoder registry, fallingback to a function named
[decodername]_decoder
on the internalcore image object. That function is called with theargs
tuplefrom thetile
setup in the_open
method. - Decoding: The decoder’s decode function is repeatedly called withchunks of image data.
- Cleanup: If the decoder has registered a cleanup function, it willbe called at the end of the decoding process, even if there was anexception raised.
Setup
The current conventions are that the decoder setup function is namedPyImaging_[Decodername]DecoderNew
and defined in decode.c
. Thepython binding for it is named [decodername]_decoder
and is setupfrom within the _imaging.c
file in the codecs section of thefunction array.
The setup function needs to call PyImaging_DecoderNew
and at thevery least, set the decode
function pointer. The fields ofinterest in this object are:
- decode
- Function pointer to the decode function, which has access to
im
,state
, and the buffer of data to be added to the image. - cleanup
- Function pointer to the cleanup function, has access to
state
. - im
- The target image, will be set by Pillow.
- state
- An ImagingCodecStateInstance, will be set by Pillow. The contextmember is an opaque struct that can be used by the decoder to storeany format specific state or options.
- pulls_fd
- EXPERIMENTAL – WARNING, interface may change. If set to 1,
state->fd
will be a pointer to the Python file like object. Thedecoder may use the functions incodec_fd.c
to read directlyfrom the file like object rather than have the data pushed through abuffer. Note that this implementation may be refactored until thiswarning is removed.
3.3.0 新版功能.
Decoding
The decode function is called with the target (core) image, thedecoder state structure, and a buffer of data to be decoded.
Experimental – If pulls_fd
is set, then the decode functionis called once, with an empty buffer. It is the decoder’sresponsibility to decode the entire tile in that one call. The rest ofthis section only applies if pulls_fd
is not set.
It is the decoder’s responsibility to pull as much data as possibleout of the buffer and return the number of bytes consumed. The nextcall to the decoder will include the previous unconsumed tail. Thedecoder function will be called multiple times as the data is readfrom the file like object.
If an error occurs, set state->errcode
and return -1.
Return -1 on success, without setting the errcode.
Cleanup
The cleanup function is called after the decoder returns a negativevalue, or if there is a read error from the file. This function shouldfree any allocated memory and release any resources from externallibraries.
Writing Your Own File Decoder in Python
Python file decoders should derive fromPIL.ImageFile.PyDecoder
and should at least override thedecode method. File decoders should be registered usingPIL.Image.register_decoder()
. As in the C implementation ofthe file decoders, there are three stages in the lifetime of aPython-based file decoder:
- Setup: Pillow looks for the decoder in the registry, theninstantiates the class.
- Decoding: The decoder instance’s
decode
method is repeatedlycalled with a buffer of data to be interpreted. - Cleanup: The decoder instance’s
cleanup
method is called.