Hi there,
I am using the following setup:
Windows 7
python 2.7.12 (Anaconda)
Pillow 3.4.2
I am using scanned documents in .tiff format (TIFF, mode="1")
I am trying to merge .tiff images to one singe document with multi-pages with the following code:
im=Image.open(path_tmp+'/'+list_file[0])
im.load()
for i in list_file[1:]:
print i
tmp_im = Image.open(path_tmp+'/'+i)
tmp_im.load()
print tmp_im.format, tmp_im.size, tmp_im.mode
list_im.append(tmp_im)
print list_im
im.save("test.tiff", save_all=True,append_images=list_im)
I was expecting that the "test.tiff" document will contain all the .tiff images that are in the list: "list_im" (one page per tiff image). But I see a one page document with the first .tiff from the list and no message and no warning.
here what the above code is displaying:
42526530005_1032__1.tiff
TIFF (2455, 3462) 1
42526530005_1032__2.tiff
TIFF (2462, 3474) 1
42526530005_1032__3.tiff
TIFF (2451, 3470) 1
42526530005_1032__4.tiff
TIFF (2455, 3481) 1
[<PIL.TiffImagePlugin.TiffImageFile image mode=1 size=2455x3462 at 0x36137898>, <PIL.TiffImagePlugin.TiffImageFile image mode=1 size=2462x3474 at 0x36137DA0>, <PIL.TiffImagePlugin.TiffImageFile image mode
gePlugin.TiffImageFile image mode=1 size=2455x3481 at 0x361477F0>]
I was thinking that save_all=True and append_images=list_im will add the other image from the list. Did I misunderstood the documentation ? Should I resize each image to have all the same size ?
I also realized that on windows, using im.close() is not working as I was expecting and when I try later the remove the file, Windows crashed and complain that the file is used by another application. Using im.close() do the trick.
Thanks a lot
Cheers
Fabien
https://pillow.readthedocs.io/en/3.4.x/handbook/image-file-formats.html#saving-sequences - I can tell you that at the moment, append_images is currently only supported for GIF.
Hi Andrew,
ah, ok. I saw the save_all option so I was thinking that append_images was present too for TIFF
https://pillow.readthedocs.io/en/3.4.x/handbook/image-file-formats.html#tiff
save_all
If true, Pillow will save all frames of the image to a multiframe tiff document.
New in version 3.4.0.
I also saw this discussion and I got the impression that it was done and working for TIFF as well:
https://github.com/python-pillow/Pillow/issues/733
I guess I didn't undertood the difference between a multiframe image and a list of image
Thanks
Cheers
Fabien
There was a patch for tiffs that was merged late in the 3.4 cycle
Hi Eric,
is the patch already available ? I am using Pillow 3.4.2 and using pip it say that Pillow is already up-to-date.
Thanks
Cheers
Fabien
@tarrade Here is a stand-alone version, that also shows how to use it (see main at the end). save_all is also supported, see Tests/test_file_tiff.py::test_tiff_save_all. https://gist.github.com/lambdafu/6d537cf30a6430535593f2d31b05d68a
@tarrade Reading the conversation again, I think wiredfool referred to save_all, not append_images. So I guess my previous post was redundantly redundant :)
Hi there,
Sorry I never worked with images before and I am a little bit confuse by what is the difference between save_all and append_images options and what is a multi-frame image
@lambdafu : can explain to me the difference between these 2 options ?
I have many one page document .tiff images and I want to put all of them in one single multi-page document (one page = one .tiff image).
Thanks again
Cheers
Fabien
I'm having the same problem, I have been able to create a multipage tiff file from a folder full of tiff files with ImageMagik, but when doing it with Pillow 3.4.2 and the AppendingTiffWriter helper class I get a tiff file of more-or-less same size as the ImageMagik one, but contains a single page with a big black image.The code I'm using to generate the tiff file is:
with AppendingTiffWriter(outdir+'.tiff', True) as tiff_out:
for tiff_in in listdir(outdir):
with open(join(outdir, tiff_in)) as tiff_in:
for idx in range(tiff_in.n_frames):
tiff_in.seek(idx)
tiff_in.save(tiff_out, 'tiff')
This way I run over all the frames of the input tiff files (although the have a single page) and save them on the output tiff file. Could I be doing something wrong here?
@tarrade if you don't have a multipage tiff to begin with, you use the AppendingTiffWriter directly.
@piranna: You need to call new_frame on the AppendingTiffWriter like this:
with AppendingTiffWriter(OUTFILE) as tf:
for extend in extends:
im = Image.effect_mandelbrot(size, extend, 100)
im.save(tf)
tf.newFrame()
@piranna: You need to call new_frame on the AppendingTiffWriter
By doing so with
with AppendingTiffWriter(outdir+'.tiff', True) as tiff_out:
for tiff_in in listdir(outdir):
with open(join(outdir, tiff_in)) as tiff_in:
for idx in range(tiff_in.n_frames):
tiff_in.seek(idx)
tiff_in.save(tiff_out, 'tiff')
tiff_out.newFrame()
y get the next exceptions:
multiprocessing.pool.RemoteTraceback:
"""
Traceback (most recent call last):
File "./imagextractor.py", line 96, in cutAndSave
tiff_out.newFrame()
File "/home/piranna/Trabajo/HBP/imagextractor/multiPageTiff.py", line 113, in newFrame
self.setup()
File "/home/piranna/Trabajo/HBP/imagextractor/multiPageTiff.py", line 81, in setup
raise RuntimeError("Invalid TIFF file header")
RuntimeError: Invalid TIFF file header
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/lib/python3.5/multiprocessing/pool.py", line 119, in worker
result = (True, func(*args, **kwds))
File "/usr/lib/python3.5/multiprocessing/pool.py", line 44, in mapstar
return list(map(*args))
File "./imagextractor.py", line 117, in cutAndSave_multiprocessing
return cutAndSave(CziFile(argv[0]), argv[1], argv[2], argv[3])
File "./imagextractor.py", line 96, in cutAndSave
tiff_out.newFrame()
File "/home/piranna/Trabajo/HBP/imagextractor/multiPageTiff.py", line 120, in __exit__
self.close()
File "/home/piranna/Trabajo/HBP/imagextractor/multiPageTiff.py", line 205, in close
self.finalize()
File "/home/piranna/Trabajo/HBP/imagextractor/multiPageTiff.py", line 103, in finalize
IFDoffset = self.readLong()
File "/home/piranna/Trabajo/HBP/imagextractor/multiPageTiff.py", line 168, in readLong
value, = unpack(self.longFmt, self.f.read(4))
AttributeError: 'AppendingTiffWriter' object has no attribute 'longFmt'
"""
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "./imagextractor.py", line 156, in <module>
main(parser.parse_args())
File "./imagextractor.py", line 138, in main
regions = pool.map(cutAndSave_multiprocessing, process_params)
File "/usr/lib/python3.5/multiprocessing/pool.py", line 260, in map
return self._map_async(func, iterable, mapstar, chunksize).get()
File "/usr/lib/python3.5/multiprocessing/pool.py", line 608, in get
raise self._value
AttributeError: 'AppendingTiffWriter' object has no attribute 'longFmt'
Seems AppendingTiffWriter would need to have add longFmt... what's that used for?
Also, shouldn't newFrame be called internally?
Ok, I was using an outdated version of the standalone class, I changed the code to use the one included with Pillow 3.4.2 but now I get the next error:
multiprocessing.pool.RemoteTraceback:
"""
Traceback (most recent call last):
File "/usr/lib/python3.5/multiprocessing/pool.py", line 119, in worker
result = (True, func(*args, **kwds))
File "/usr/lib/python3.5/multiprocessing/pool.py", line 44, in mapstar
return list(map(*args))
File "./imagextractor.py", line 122, in cutAndSave_multiprocessing
return cutAndSave(CziFile(argv[0]), argv[1], argv[2], argv[3])
File "./imagextractor.py", line 101, in cutAndSave
tiff_in.save(tiff_out, format="tiff", save_all=True)
File "/usr/lib/python3/dist-packages/PIL/Image.py", line 1667, in save
save_handler = SAVE_ALL[format.upper()]
KeyError: 'TIFF'
"""
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "./imagextractor.py", line 161, in <module>
main(parser.parse_args())
File "./imagextractor.py", line 143, in main
regions = pool.map(cutAndSave_multiprocessing, process_params)
File "/usr/lib/python3.5/multiprocessing/pool.py", line 260, in map
return self._map_async(func, iterable, mapstar, chunksize).get()
File "/usr/lib/python3.5/multiprocessing/pool.py", line 608, in get
raise self._value
KeyError: 'TIFF'
The code I'm using is taken from the Pillow tests:
with open(outdir+'.tiff', 'w') as tiff_out:
for tiff_in in listdir(outdir):
with Image.open(join(outdir, tiff_in)) as tiff_in:
tiff_in.save(tiff_out, format="tiff", save_all=True)
@lambdafu thanks and sorry for the delay. By using a modified version of your suggestion it works:
with PIL.TiffImagePlugin.AppendingTiffWriter("./test.tiff",True) as tf:
for tiff_in in list_file:
with open(tiff_in) as tiff_in:
im= Image.open(tiff_in)
im.save(tf)
tf.newFrame()
today I tried with pillow 4.0.0
On my side, I can do what I want so this issue can be closed and maybe some example added to the doc to help other user.
Thanks
Cheers
Fabien
@tarrade, could you be able to provide a complete example? I'm using pillow 4.0.0 installed with PIP but I'm not able to import anyway the AppendingTiffWriter class... :-/
Hi @piranna,
I am using pillow 3.4.2 (on Windows but I tried with 4.0.0 on Mac)
from PIL import Image
from PIL import TiffImagePlugin
with TiffImagePlugin.AppendingTiffWriter(path_tmp+'/'+merged_file_name,True) as tf:
for tiff_in in list_file:
try:
im= Image.open(path_tmp+'/'+tiff_in)
im.save(tf)
tf.newFrame()
im.close()
the name of my output file is: path_tmp+'/'+merged_file_name
list_file is a list of my file (only the file name, not the path)
Hope this help
Cheers
Fabien
Thank you @tarrade :-) The problem was not about the code itself but about the importing, since I'm using Python3 and used the regular pip of Python2 to install Pillow, thanks to your code I was conscious of my dumb error :-P
Hi , I am using below code (same as above) to merge tiff files into one tiff file. But , after merging , I see only one tiff file/image in the result. Kindly help asap. Thanks in advance.
from PIL import Image
from PIL import TiffImagePlugin
with TiffImagePlugin.AppendingTiffWriter(SRC_FILES_FOLDER_PATH +'\\Merged.tif',True) as tf:
for tiff_in in fileNames:
im= Image.open(SRC_FILES_FOLDER_PATH +'\\'+tiff_in,"r")
im.save(tf)
tf.newFrame()
print('in')
im.close()
@sureshdarsru I'm able to adjust and run your code successfully. Would you be able to provide some of the images that you are opening?
Hi Andrew
Really I am happy to see your response. I have got the confidence that I
can resolve this issue quickly. Pls find attached few TIFF files created
using MSPAINT.
After the merging done ,I see the size of resulting file got increased. But
I see always the first file's image.
Kind Note: If it will work for you then , issue could be over PIL / PILLOW
Installation. I had PIL. Later , I installed Pillow. I am using Python 3*.
Regards
Suresh
The files did not appear. I suggest you try adding them through the GitHub site, rather than attaching them to a reply e-mail.
Hi Andrew
I see the issue with Image viewer. I think think , I am facing this issue ie I can see only one page after I have installed OpenText suite of products.
Meanwhile, I have one more request. I have one more requirement. I would need to combine multiple AFP type of files into one AFP file. Please let me know which python's library I have to use for the same. If you have any sample code , can I get it pls.
Thanks in advance again.
Regards
Suresh
Hi Andrews
Missed to mention that my TIFF image files combining issue got resolved. Thanks for your help.
As mentioned above , could you reply on AFP issue.
Regards
Suresh
I'm not familiar with the AFP file format. If you have a Pillow question unrelated to this thread, please create a new issue.
Yes. I will do . Thanks Andrew for your quickest responses :-)
Most helpful comment
@tarrade if you don't have a multipage tiff to begin with, you use the AppendingTiffWriter directly.
@piranna: You need to call new_frame on the AppendingTiffWriter like this: