I wrote a program (as an extension) to take selected photos from the camera roll, combine them vertically and save the combined photo to the camera roll. This would be used for combining multiple screen shots of say a web page where you capture parts of the page while scrolling through it. I know you can buy an app(s) that do this but this seems like a perfect thing for Pythonista (plus an opportunity to learn).
I have the code merging the photos (at least a few) but Pythonista crashes when more than 3 or so pics are selected and when trying to save to the camera roll. I added the startup code to log crash info but it is always empty. Looking for any help anyone may have.
import appex
from PIL import Image
from PIL.ExifTags import TAGS
import photos
# standard get exif code - needed for image size
def get_exif(fn):
ret = {}
i = Image.open(fn)
info = i._getexif()
for tag, value in info.items():
decoded = TAGS.get(tag, tag)
ret[decoded] = value
return ret
def main():
if not appex.is_running_extension():
print('This script is intended to be run from the sharing extension.')
return
images = appex.get_images()
print(f'len(images) = {len(images)})')
# get the widths/heights of the images
widths, heights = zip(*(i.size for i in images))
# this is stacking vertically so the width is the max width of all the pics
max_width = max(widths)
# since stacking vertically the height is the total heights of the pics
total_height = sum(heights)
print(f'total height = {total_height}')
print(f'max width = {max_width}')
# create a new blank image in the required size
new_im = Image.new('RGBA', (max_width, total_height))
print(f'new_im.size = {new_im.size}')
# now assemble the merged pic
# y_offset controls the pixel location of where each image is added
# to the new image - to add each end-to-end
# starting at the top which is y = 0
y_offset = 0
# loop through all passed images
for im in images:
# paste in the image at the left edge (x=0) and current offset for y
new_im.paste(im, (0,y_offset))
print(f'y_offset = {y_offset}')
# increase the offset by the height of current pic
y_offset += im.size[1]
# save the new image to the camera roll
photos.save_image(new_im)
if __name__ == '__main__':
main()