• jm2466

    Um... because you never told me to until now??? :) kidding of course. But honestly have no real answer to that question. Possibly because I wanted to save an in-memory image and not have to save the file locally first (at least that was the initial plan but is not where I am at with it now). Not sure if create image asset supports that (I tried passing the variable and got an error that a str is required).

    I just tried your suggestion and it works - I mean it saves the locally saved combined.jpg to the camera roll. Thanks!!!

    Any thoughts on how to get this to work without saving combined.jpg first???

    posted in Pythonista read more
  • jm2466

    Thanks. I tried that but it crashes trying to save the image to the camera roll. I can open the jpg in Pythonista and manually add it to the camera roll. Here are the lines at the end that I added:

        new_im.save('combined.jpg')
        del new_im
        photos.save_image(Image.open('combined.jpg'))
    
    

    posted in Pythonista read more
  • jm2466

    Unfortunately I do not.

    But if you look at the code in my original post I added one line in the for loop to delete the image (below is the loop from that post with the del at the end)

        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]
            del im 
    

    As mentioned that seemed to fix the issue pasting more than a few images into the new one.

    This line crashes Pythonista:

        photos.save_image(new_im)
    

    But I can save it to the Pythonista file system with the following:

        new_im.save('combined.jpg')
    

    posted in Pythonista read more
  • jm2466

    I added the del image after it is pasted into the merged image and that part appears to work. The program is now having a problem saving the merged image to the camera roll. If I instead save it to the Pythonista file system it works and is a workaround until the camera roll save is figured out. Any other thoughts on how to fix the camera roll save is greatly appreciated.

    posted in Pythonista read more
  • jm2466

    Thanks!!

    posted in Pythonista read more
  • jm2466

    Sorry for the delay in replying and thanks for the help.

    So from the above suggestions it appears deleting the photos once merged may be the best solution but I am not quite sure how to do that correctly. This is an extension so will receive the selected photos that I believe are just references/names of the photos and not the actual image - is that correct? My code then loops through the list and actually gets the photos and adds to a list. First it sounds like I should not get all of them before processing but rather merge each one as it is retrieved. Once that is done I need to “delete” it in the program, or really just delete/remove it from program memory what is the best way to do this without deleting the actual photo?

    Thanks

    posted in Pythonista read more
  • jm2466

    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()
    

    posted in Pythonista read more
  • jm2466

    Thought I posted the code to merge two albums but it appears I did not. So here it is:

    import photos
    from datetime import datetime
    
    albums = photos.get_albums()
    
    # prob better ways to do this but this works, loop through albums and create list
    # where album name equals name in quotes, then take first one (should only be 1)
    sourcealbum = [a for a in albums if a.title == 'put album name here'][0]
    print(f'Nbr photos in sourcealbum: {len(sourcealbum.assets)}')
    
    sourcealbum_2 = [a for a in albums if a.title == 'put second album name here'][0]
    print(f'Nbr photos in sourcealbum_2: {len(sourcealbum_2.assets)}')
    
    # this requires that the dest album exists as it will not create it
    destalbum = [a for a in albums if a.title == 'put dest album name here']
    
    if len(destalbum) > 0:
        destalbum = destalbum[0]
    print(f'destalbum: {destalbum}')
    
    # first create a merged list of both albums
    mergedlist = sourcealbum.assets.copy() + sourcealbum_2.assets.copy()
    
    print(f'Nbr photos in mergedlist: {len(mergedlist):,}')
    
    # sort merged list by creation date
    mergedlistsorted = sorted(mergedlist, key=lambda x: x.creation_date)
    
    # add the sorted assets to the destination album
    destalbum.add_assets(mergedlistsorted)
    
    # I always put this at the end in scripts to know for sure when it finished
    print('***** DONE *****')
    

    So this merged to albums with about 900 pics in one and 800 in another almost instantly. The resulting album had 1700+ pics in the correct order and the pics were not physically duplicated. Do not know how I could have done this any other way on the phone. I do not sync my iphone with a Mac so if I did this on Windows I would lose the live photo part of the iphone pics.

    Thanks everyone that helped!

    posted in Pythonista read more
  • jm2466

    Thanks! That worked. Now just having a bit of an issue decoding the exif.

    Here is what I am trying to do. I have 2 albums from a recent vacation with a lot of photos in each. One is from my phone (all live photos) and the other is from my dslr. They are each in date/time order and I want to merge both into one album sorted by date/time (I want to do this on the phone as to not lose the live photos). This logic is fairly easy as long as I can get photos from the two albums (which I can now - thanks!) and get the exif info from each to compare (the dates outside the exif may not reflect the actual time the picture was taken). The Image.info appears to have the exif data but looks to be Unicode or something. Have not had a chance to look into it further yet so if you have a quick solution to this that would be great.

    Thanks again

    posted in Pythonista read more
  • jm2466

    I tried searching but it was not clear from what I found. I want to copy a photo from one album to another without creating a physical copy. In some of the examples it appears the image is opened, some reference a temp jpg on the file system or something. Anyhow I thought I could just get a reference/pointer to the photo from one album then add that reference to the other album. Anyone do this in straight python or does it require objc calls?

    Thanks

    posted in Pythonista read more

Internal error.

Oops! Looks like something went wrong!