I'm trying to open a source image, read its frames and append these to a new image object. It works to a point, then I receive a TypeError
. The "source images" are an existing TIFF, then a set of documents I've validated and converted to TIFF.
from PIL import Image, ImageSequence, TiffImagePlugin
def insert_into_tiff(image_source_path, passed_images, delete_file=False, delete_converted=True):
# create a temporary image to hold all ensuing frames
temp_image_path = TEMP_IMG / 'temp_{}'.format( Path(image_source_path).name )
with TiffImagePlugin.AppendingTiffWriter(temp_image_path, True) as image_to_be_appended:
# append frames from the original image
append_tiff_sequences(image_source_path, image_to_be_appended)
# append frames from each of the validated files / "passed_images"
for p in passed_images:
source_path = TEMP_IMG / p['new_name'] # the validated file
append_tiff_sequences(source_path, image_to_be_appended)
def append_tiff_sequences(image_source_path, image_to_be_appended):
print("append {} frames from {}".format(get_image_sequence_frame_count(image_source_path), image_source_path))
# open the source file
with Image.open(image_source_path) as additional_images:
# iterate over it's frames
for frame in ImageSequence.Iterator(additional_images):
frame_copy = frame.copy() # copy the frame
frame_copy.save(image_to_be_appended) # append to the temporary image
image_to_be_appended.newFrame()
frame_copy.close()
def get_image_sequence_frame_count(image_path):
return Image.open(image_path).n_frames
There are 13 files in /TEMP_IMG
:
/TEMP_IMG contents:
[PosixPath('/code/media/temp/RT170822001.tiff'), PosixPath('/code/media/temp/RT170822002.tiff'), PosixPath('/code/media/temp/RT170822003.tiff'), PosixPath('/code/media/temp/RT170822004.tiff'), PosixPath('/code/media/temp/RT170822005.tiff'), PosixPath('/code/media/temp/RT170822006.tiff'), PosixPath('/code/media/temp/RT170822007.tiff'), PosixPath('/code/media/temp/RT170822008.tiff'), PosixPath('/code/media/temp/RT170822009.tiff'), PosixPath('/code/media/temp/RT170822010.tiff'), PosixPath('/code/media/temp/RT170822011.tiff'), PosixPath('/code/media/temp/RT170822012.tiff'), PosixPath('/code/media/temp/RT170822013.tiff')]
The process is fine until it reaches file 12
append 1 frames from /code/media/unmarked/RT170822001.tiff
append 1 frames from /code/media/temp/RT170822001.tiff
append 2 frames from /code/media/temp/RT170822002.tiff
append 2 frames from /code/media/temp/RT170822003.tiff
append 1 frames from /code/media/temp/RT170822004.tiff
append 1 frames from /code/media/temp/RT170822005.tiff
append 1 frames from /code/media/temp/RT170822006.tiff
append 1 frames from /code/media/temp/RT170822007.tiff
append 2 frames from /code/media/temp/RT170822008.tiff
append 1 frames from /code/media/temp/RT170822009.tiff
append 1 frames from /code/media/temp/RT170822010.tiff
append 1 frames from /code/media/temp/RT170822011.tiff
append 1 frames from /code/media/temp/RT170822012.tiff
Where it fails with the following:
ERROR: test_scan_add_allows_valid_docs_and_screenshots_to_be_added_to_image (main_app.tests.test_EndToEnd.ImagesAvailableTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/code/main_app/tests/test_EndToEnd.py", line 355, in test_scan_add_allows_valid_docs_and_screenshots_to_be_added_to_image
response = self.client.post( request_url, data)
File "/usr/local/lib/python3.10/site-packages/django/test/client.py", line 751, in post
response = super().post(path, data=data, content_type=content_type, secure=secure, **extra)
File "/usr/local/lib/python3.10/site-packages/django/test/client.py", line 407, in post
return self.generic('POST', path, post_data, content_type,
File "/usr/local/lib/python3.10/site-packages/django/test/client.py", line 473, in generic
return self.request(**r)
File "/usr/local/lib/python3.10/site-packages/django/test/client.py", line 719, in request
self.check_exception(response)
File "/usr/local/lib/python3.10/site-packages/django/test/client.py", line 580, in check_exception
raise exc_value
File "/usr/local/lib/python3.10/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/usr/local/lib/python3.10/site-packages/django/core/handlers/base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python3.10/site-packages/django/views/generic/base.py", line 70, in view
return self.dispatch(request, *args, **kwargs)
File "/usr/local/lib/python3.10/site-packages/django/views/generic/base.py", line 98, in dispatch
return handler(request, *args, **kwargs)
File "/code/main_app/views.py", line 187, in post
processed_images = handle_additional_images(request.user, pk, documents, base64_image)
File "/code/main_app/helpers/processing.py", line 83, in handle_additional_images
insert_into_tiff( existing_image_path, processed_images['passed'] )
File "/code/main_app/helpers/image_manipulation.py", line 118, in insert_into_tiff
append_tiff_sequences(source_path, image_to_be_appended)
File "/code/main_app/helpers/image_manipulation.py", line 129, in append_tiff_sequences
frame_copy.save(image_to_be_appended) # append to the temporary image
File "/usr/local/lib/python3.10/site-packages/PIL/Image.py", line 2300, in save
save_handler(self, fp, filename)
File "/usr/local/lib/python3.10/site-packages/PIL/TiffImagePlugin.py", line 1810, in _save
e = Image._getencoder(im.mode, "libtiff", a, encoderconfig)
File "/usr/local/lib/python3.10/site-packages/PIL/Image.py", line 458, in _getencoder
return encoder(mode, *args + extra)
TypeError: argument 5 must be str, not PosixPath
If I use TiffImagePlugin.AppendingTiffWriter
and append to the existing image / image_source_path
(ie no temporary / intermediary image), it works fine but overwrites the existing image's first frame (I expect 17 frames, it completes with 16 and I can see the first frame is no longer there).
I have also used str(<path>)
but that doesn't solve the issue either. I've not been able to figure out what argument 5
for the encoder
is because in the source the encoder_name
isn't clear in the source.
A senior dev solved it. The issue was this line:
temp_image_path = TEMP_IMG / 'temp_{}'.format( Path(image_source_path).name )
Using os.path.join
instead solved the issue:
temp_image_path = os.path.join(TEMP_IMG, 'temp_{}'.format( Path(image_source_path).name ))
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.