[Image-SIG] patch -- was: help me to contribute -- writing multi-page TIFF ....

Sebastian Haase haase at msg.ucsf.edu
Tue Apr 15 16:35:49 CEST 2008


On Mon, Apr 14, 2008 at 7:17 PM, Waldemar Osuch
<waldemar.osuch at gmail.com> wrote:
> On Mon, Apr 14, 2008 at 3:40 AM, Sebastian Haase <haase at msg.ucsf.edu> wrote:
>  > Hi,
>  >  Since TIFF seems to be the most wanted format in our group (microscopy
>  >  images) I now want to add write support for multi-page tiff image.
>  >
>  >  I was wondering if people here could give me some hints and / or
>  >  references on how to go about this ?
>  >
>  >  Of course if someone knows about existing code to write multi-page
>  >  tiff in Python -- please speak up now ;-)  (( wxPython maybe ?))
>
>  I have used http://www.haynold.com/software_projects/2004/pytiff/ before.
>  The project seems to abandoned but it worked very nicely for my simple needs.
>
>  Another option worth considering is to use something like:
>   http://www.libtiff.org/ in combination with subprocess module.
>

Hi all,
I'm happy to submit a patch.
It works for me.
It modifies TiffImagePlugin.py so that I can use another (external)
function to write multi page TIFF files.
The reason I need an extra function is that I did not see how PIL is
*supposed to* handle multi-page aka. animation Images.
As far as I could tell, an Image class object is always only a "2D"
image; loading of multi-page (or animation) images is only supported
via the ImageFile class and its seek function.

My "external" save function is special to my own environment, but
should be easily adjustable.
It safes higher dimensional numpy arrays and makes use of my own
array2image() function:
{{{
def saveTiffMultipage(arr, fn, rescaleTo8bit=False, **params):
    if arr.ndim == 4:
        if arr.shape[1] not in (2,3,4):
            raise ValueError, "can save 4d arrays (color) only with
second dim of len 2..4 (RG[B[A]])"
    elif arr.ndim != 3:
        raise ValueError, "can only save 3d (grey) or 4d (color) arrays"

    fp = open(fn, 'w+b')

    ifd_offsets=[]

    if rescaleTo8bit:
        mi,ma = float(arr.min()), float(arr.max())
        ra = ma-mi

    params["_debug_multipage"] = True
    for z in range(arr.shape[0]):
        if rescaleTo8bit:
            a=(arr[z]-mi)*255./ra
            ii = array2image(a.astype(N.uint8))
        else:
            ii = array2image(arr[z])

        fp.seek(0,2) # go to end of file
        if z==0:
            # ref. PIL  TiffImagePlugin
            # PIL always starts the first IFD at offset 8
            ifdOffset = 8
        else:
            ifdOffset = fp.tell()

        ii.save(fp, format="TIFF", **params)

        if z>0: # correct "next" entry of previous ifd -- connect !
            ifdo = ifd_offsets[-1]
            fp.seek(ifdo)
            ifdLength = ii._debug_multipage.i16(fp.read(2))
            fp.seek(ifdLength*12,1) # go to "next" field near end of ifd
            fp.write(ii._debug_multipage.o32( ifdOffset ))

        ifd_offsets.append(ifdOffset)
    fp.close()
}}}

Attached is the needed patch for TiffImagePlugin.py.
It is against the version I got from svn yesterday.
My version also contains someone else's patch for big-/little-endian
byte order handling.

Regards,
Sebastian Haase

PS: What is actually the process that patches might get into the
official PIL code ? is there a plan for a 1.1.7 version ?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: tiff.multipage.patch
Type: application/octet-stream
Size: 11724 bytes
Desc: not available
Url : http://mail.python.org/pipermail/image-sig/attachments/20080415/6bd31b98/attachment.obj 


More information about the Image-SIG mailing list